Source code for petrelic.petlib.pairing

r"""
This module provides a Python wrapper around RELIC's pairings using petlib's
interface: operations in :py:obj:`petrelic.native.pairings.G1` and
:py:obj:`petrelic.native.pairings.G2` are written additively, whereas operations in
:py:obj:`petrelic.native.pairings.GT` are written multiplicatively.

"""
from petrelic.bindings import _FFI, _C
from petrelic.bn import Bn, force_Bn_other
from petrelic.native.pairing import NoAffineCoordinateForECPoint

import petrelic.native.pairing as native


[docs]class BilinearGroupPair: """ A bilinear group pair. Contains two origin groups G1, G2 and the image group GT. The underlying ``bplib.bp.BpGroup`` object is also embedded. """ def __init__(self): self.GT = GTGroup() self.G1 = G1Group() self.G2 = G2Group()
[docs] def groups(self): """ Returns the three groups in the following order : G1, G2, GT. """ return self.G1, self.G2, self.GT
[docs]class G1Group(native.G1): """G1 group""" @classmethod def _element_type(cls): return G1Elem
[docs] def check_point(self, pt): """Ensures the point is on the curve. Example: >>> G = G1Group() >>> G.check_point(G.generator()) True >>> G.check_point(G.infinite()) True """ return type(pt) == self._element_type() and (pt.is_valid() or pt.is_infinite())
[docs] @classmethod def infinite(cls): """The point at infinity. Alias for :py:meth:`G1.neutral_element` """ return cls.neutral_element()
# Not implemented: list_curves(), parameters(), get_points_from_x
[docs]class G1Elem(native.G1Element): """Element of the G1 group""" group = G1Group pt_add = native.G1Element.__add__ pt_add_inplace = native.G1Element.__iadd__ pt_sub = native.G1Element.__sub__ pt_double = native.G1Element.double pt_double_inplace = native.G1Element.idouble pt_neg = native.G1Element.__neg__ pt_neg_inplace = native.G1Element.iinverse pt_mul = native.G1Element.__mul__ pt_mul_inplace = native.G1Element.__imul__ pt_eq = native.G1Element.__eq__ is_infinite = native.G1Element.is_neutral_element export = native.G1Element.to_binary get_affine = native.G1Element.get_affine_coordinates
[docs] def pair(self, other): """Computes bilinear pairing with self and otherwise Examples: >>> G1 = G1Group() >>> G2 = G2Group() >>> GT = GTGroup() >>> G1.generator().pair(G2.generator()) == GT.generator() True >>> p = 100 * G1.generator() >>> q = 200 * G2.generator() >>> p.pair(q) == GT.generator() ** 20000 True """ if not type(other) == G2Elem: raise TypeError("Second parameter should be of type G2Elem is {}".format(type(other))) res = GTElem() _C.pc_map(res.pt, self.pt, other.pt) return res
def _get_coords(self): x, y, z = Bn(), Bn(), Bn() _C.fp_prime_back(x.bn, self.pt[0].x) _C.fp_prime_back(y.bn, self.pt[0].y) _C.fp_prime_back(z.bn, self.pt[0].z) return (x, y, z)
[docs] @classmethod def from_binary(cls, sbin, group=None): return super().from_binary(sbin)
def __repr__(self): """ Representation of G1Point Examples: >>> G1Group().infinite() G1Elem(0, 0, 0) >>> G1Group().generator() G1Elem(3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507, 1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569, 1) """ x, y, z = self._get_coords() return "G1Elem({}, {}, {})".format(x, y, z)
[docs]class G2Group(native.G2): """G2 group""" @classmethod def _element_type(cls): return G2Elem
[docs] def check_point(self, pt): """Ensures the point is on the curve. Example: >>> G = G2Group() >>> G.check_point(G.generator()) True >>> G.check_point(G.infinite()) True """ return type(pt) == self._element_type() and (pt.is_valid() or pt.is_infinite())
[docs] @classmethod def infinite(cls): """The point at infinity. Alias for :py:meth:`G2.neutral_element` """ return cls.neutral_element()
[docs]class G2Elem(native.G2Element): """Element of the G2 group""" group = G1Group pt_add = native.G2Element.__add__ pt_add_inplace = native.G2Element.__iadd__ pt_sub = native.G2Element.__sub__ pt_double = native.G2Element.double pt_double_inplace = native.G2Element.idouble pt_neg = native.G2Element.__neg__ pt_neg_inplace = native.G2Element.iinverse pt_mul = native.G2Element.__mul__ pt_mul_inplace = native.G2Element.__imul__ pt_eq = native.G2Element.__eq__ is_infinite = native.G2Element.is_neutral_element export = native.G2Element.to_binary
[docs] @classmethod def from_binary(cls, sbin, group=None): return super().from_binary(sbin)
def __repr__(self): """ Representation of G2Point Examples: >>> G2Group().infinite() G2Elem(00) >>> G2Group().generator() G2Elem(02024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb813e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e) """ pt_hex = self.to_binary().hex() return "G2Elem({})".format(pt_hex)
[docs]class GTGroup(native.GT): """GT group""" @classmethod def _element_type(cls): return GTElem
[docs] def check_elem(self, pt): """Ensures the element is an element of the group Example: >>> G = GTGroup() >>> G.check_elem(G.generator()) True >>> G.check_elem(G.unity()) True """ return type(pt) == self._element_type() and pt.is_valid()
# Not implemented: list_curves(), parameters(), get_points_from_x
[docs]class GTElem(native.GTElement): """GT element""" group = GTGroup mul_inplace = native.GTElement.__imul__ inv = native.GTElement.inverse inv_inplace = native.GTElement.iinverse sqr = native.GTElement.square sqr_inplace = native.GTElement.isquare exp = native.GTElement.__pow__ exp_inplace = native.GTElement.__ipow__ export = native.GTElement.to_binary
[docs] @classmethod def from_binary(cls, sbin, group=None): """Create an element from a byte sequence. It accepts (but ignores) group as extra argument. Example: >>> G = GTGroup() >>> byte_string = G.generator().export() # Export EC point as byte string >>> GTElem.from_binary(byte_string, G) == G.generator() # Import EC point from binary string True >>> GTElem.from_binary(byte_string) == G.generator() # Import EC point from binary string True """ return super().from_binary(sbin)
def __repr__(self): """ Representation of GTPoint Examples: >>> GTGroup().generator() GTElem(1368bb445c7c2d209703f239689ce34c0378a68e72a6b3b216da0e22a5031b54ddff57309396b38c881c4c849ec23e87193502b86edb8857c273fa075a50512937e0794e1e65a7617c90d8bd66065b1fffe51d7a579973b1315021ec3c19934f01b2f522473d171391125ba84dc4007cfbf2f8da752f7c74185203fcca589ac719c34dffbbaad8431dad1c1fb597aaa5018107154f25a764bd3c79937a45b84546da634b8f6be14a8061e55cceba478b23f7dacaa35c8ca78beae9624045b4b619f26337d205fb469cd6bd15c3d5a04dc88784fbb3d0b2dbdea54d43b2b73f2cbb12d58386a8703e0f948226e47ee89d06fba23eb7c5af0d9f80940ca771b6ffd5857baaf222eb95a7d2809d61bfe02e1bfd1b68ff02f0b8102ae1c2d5d5ab1a04c581234d086a9902249b64728ffd21a189e87935a954051c7cdba7b3872629a4fafc05066245cb9108f0242d0fe3ef0f41e58663bf08cf068672cbd01a7ec73baca4d72ca93544deff686bfd6df543d48eaa24afe47e1efde449383b676631) """ pt_hex = self.to_binary().hex() return "GTElem({})".format(pt_hex)