Multiplicative interface

The multiplicative interface uses a multiplicative notation for all three groups G1, G2, and GT. This ensures that the notation is closest to that of most cryptography papers. You can use this interface by importing

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

petrelic.multiplicative.pairing

This module provides a Python wrapper around RELIC’s pairings using a multiplicative interface: operations in petrelic.multiplicative.pairings.G1, petrelic.multiplicative.pairings.G2, and petrelic.multiplicative.pairings.GT are all 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 = (G1.generator() ** sk, G2.generator() ** sk)

(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 = G1.hash_to_point(m) ** sk

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 = G1.generator() ** a
>>> B = G2.generator() ** b
>>> A.pair(B) == G1.generator().pair(G2.generator()) ** (a * b)
True
class petrelic.multiplicative.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.multiplicative.pairing.G1[source]

G1 group.

classmethod generator()[source]

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 neutral_element()[source]

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

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

Example:
>>> generator = G1.generator()
>>> neutral = G1.neutral_element()
>>> order = G1.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 = [ G1.generator() ** x for x in [10, 25, 13]]
>>> G1.prod(elems) ==  G1.generator() ** (10 + 25 + 13)
True
classmethod unity()[source]

The unity element

Alias for G1.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 = [ G1.generator() ** x for x in [10, 25, 13]]
>>> G1.wprod(weights, elems) ==  G1.generator() ** (1 * 10 + 2 * 25 + 3 * 13)
True
class petrelic.multiplicative.pairing.G1Element[source]

Element of the G1 group.

div(other)

Divide two points

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

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

idiv(other)

Inplace division by another point

Examples:
>>> a = G1.generator() ** 10
>>> b = G1.generator() ** 10
>>> a /= G1.generator() ** 3
>>> _ = b.idiv(G1.generator() ** 3)
>>> a == b
True
>>> a == G1.generator() ** 7
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 multiplication by another element

Examples:
>>> a = G1.generator() ** 10
>>> b = G1.generator() ** 10
>>> a *= G1.generator() ** 3
>>> _ = b.imul(G1.generator() ** 3)
>>> a == b
True
>>> a == G1.generator() ** 13
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
ipow(other)

Inplace raise element to the power of a scalar

Examples:
>>> g = G1.generator()
>>> a = G1.generator()
>>> _ = a.ipow(3)
>>> g * g * g == a
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
isquare()[source]

Inplace square of the current element.

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

Multiply two elements

This method is aliased by a * b.

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

Check that the points are different.

pair(other)[source]

Pair element with another element in G2

Computes the bilinear pairing between self and another element in petrelic.multiplicative.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
pow(other)

Raise element to the power of a scalar

This method is aliased by el ** n.

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

Return the square of the current element

Example:
>>> generator = G1.generator()
>>> elem = generator.square()
>>> elem == generator ** 2
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.multiplicative.pairing.G2[source]
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 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 prod(elems)[source]

Efficient product of a number of elements

In the current implementation this function is not optimized.

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

The unity element

Alias for G2.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 = [ G2.generator() ** x for x in [10, 25, 13]]
>>> G2.wprod(weights, elems) ==  G2.generator() ** (1 * 10 + 2 * 25 + 3 * 13)
True
class petrelic.multiplicative.pairing.G2Element[source]

Element of the G2 group.

div(other)

Divide two points

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

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

idiv(other)

Inplace division by another point

Examples:
>>> a = G2.generator() ** 10
>>> b = G2.generator() ** 10
>>> a /= G2.generator() ** 3
>>> _ = b.idiv(G2.generator() ** 3)
>>> a == b
True
>>> a == G2.generator() ** 7
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 multiplication by another element

Examples:
>>> a = G2.generator() ** 10
>>> b = G2.generator() ** 10
>>> a *= G2.generator() ** 3
>>> _ = b.imul(G2.generator() ** 3)
>>> a == b
True
>>> a == G2.generator() ** 13
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
ipow(other)

Inplace raise element to the power of a scalar

Examples:
>>> g = G2.generator()
>>> a = G2.generator()
>>> _ = a.ipow(3)
>>> g * g * g == a
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
isquare()[source]

Inplace square of the current element.

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

Multiply two elements

This method is aliased by a * b.

Examples:
>>> a = G2.generator() ** 10
>>> b = G2.generator() ** 40
>>> a * b == G2.generator() ** 50
True
>>> a.mul(b) == G2.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 = G2.generator()
>>> g * g == g ** 2
True
>>> g * g == g.pow(2)
True
square()[source]

Return the square of the current element

Example:
>>> generator = G2.generator()
>>> elem = generator.square()
>>> elem == generator ** 2
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.multiplicative.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.multiplicative.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