def check_pairing(participantG1, participantG2, previousParticipantG1):
    # G1 point for participant
    participant_g1_x = FQ(int(participantG1['x']))
    participant_g1_y = FQ(int(participantG1['y']))

    participant_g1 = (participant_g1_x, participant_g1_y)

    # G2 point for participant
    participant_g2_x = FQ2(
        [int(participantG2['x']['c0']),
         int(participantG2['x']['c1'])])
    participant_g2_y = FQ2(
        [int(participantG2['y']['c0']),
         int(participantG2['y']['c1'])])

    participant_g2 = (participant_g2_x, participant_g2_y)

    # G1 point for previous participant
    previous_participant_g1_x = FQ(int(previousParticipantG1['x']))
    previous_participant_g1_y = FQ(int(previousParticipantG1['y']))

    previous_participant_g1 = (previous_participant_g1_x,
                               previous_participant_g1_y)

    e1 = bn128.final_exponentiate(bn128.pairing(G2, participant_g1))
    e2 = bn128.final_exponentiate(
        bn128.pairing(participant_g2, previous_participant_g1))

    pairing_result = (e1 == e2)

    assert (pairing_result == True)
Exemple #2
0
def OpBLS_Verify(arg):
    op = json.loads(arg)

    verified = False

    g1_x = to_int(op['g1_x'])
    g1_y = to_int(op['g1_y'])

    g1 = [FQ(g1_x), FQ(g1_y), FQ.one()]

    if is_on_curve(g1, b) == False:
        r = json.dumps(verified)
        return bytes(r, 'utf-8')

    g1 = G1_to_pubkey(g1)

    g2_v = to_int(op['g2_v'])
    g2_w = to_int(op['g2_w'])
    g2_x = to_int(op['g2_x'])
    g2_y = to_int(op['g2_y'])

    g2 = (FQ2((g2_v, g2_x)), FQ2((g2_w, g2_y)), FQ2.one())
    try:
        g2 = G2_to_signature(g2)
    except:
        r = json.dumps(verified)
        return bytes(r, 'utf-8')

    msg = bytes.fromhex(op['cleartext'])

    verified = bls_pop.Verify(g1, msg, g2)

    r = json.dumps(verified)
    return bytes(r, 'utf-8')
Exemple #3
0
def OpBLS_G1_Add(arg):
    op = json.loads(arg)
    a_x = to_int(op['a_x'])
    a_y = to_int(op['a_y'])
    b_x = to_int(op['b_x'])
    b_y = to_int(op['b_y'])

    if (a_x % MOD, a_y % MOD) == (0, 0):
        return
    if (b_x % MOD, b_y % MOD) == (0, 0):
        return

    A = [FQ(a_x), FQ(a_y), FQ.one()]
    B = [FQ(b_x), FQ(b_y), FQ.one()]

    if not (is_on_curve(A, b) and subgroup_check(A)):
        return
    if not (is_on_curve(B, b) and subgroup_check(B)):
        return

    result = add(A, B)

    result = [str(result[0] / result[2]), str(result[1] / result[2])]
    r = json.dumps(result)
    return bytes(r, 'utf-8')
Exemple #4
0
def point_from_eth(p):
    """
    Convert a tuple point in G1 to a point in G1 compatible with py-ecc.
    Args:
        p (Tuple(int,int,int,int)): A tuple representing the point in G1

    Returns:
        A point in G1 which is compatible with py-ecc
    """
    x, y = p
    return (FQ(x), FQ(y), FQ(1))
Exemple #5
0
def OpBLS_IsG1OnCurve(arg):
    op = json.loads(arg)
    x = to_int(op['g1_x'])
    y = to_int(op['g1_y'])

    g1 = [FQ(x), FQ(y), FQ.one()]

    if is_valid([x, y]) == False:
        return

    #r = json.dumps(is_on_curve(g2, b2))
    r = json.dumps(is_on_curve(g1, b) and subgroup_check(g1))
    return bytes(r, 'utf-8')
Exemple #6
0
def OpBLS_G1_Neg(arg):
    op = json.loads(arg)
    a_x = to_int(op['a_x'])
    a_y = to_int(op['a_y'])

    if (a_x % MOD, a_y % MOD) == (0, 0):
        return

    A = [FQ(a_x), FQ(a_y), FQ.one()]

    result = neg(A)

    result = [str(result[0] / result[2]), str(result[1] / result[2])]
    r = json.dumps(result)
    return bytes(r, 'utf-8')
Exemple #7
0
def OpBLS_Compress_G1(arg):
    op = json.loads(arg)
    x = to_int(op['g1_x'])
    y = to_int(op['g1_y'])

    if (x % MOD, y % MOD) == (0, 0):
        return

    g1 = [FQ(x), FQ(y), FQ.one()]

    compressed = compress_G1(g1)
    if is_valid([x, y]) == True and is_on_curve(g1, b):
        decompressed = decompress_G1(compressed)
        assert g1[0] == decompressed[0] and g1[1] == decompressed[1]

    r = json.dumps(str(compressed))
    return bytes(r, 'utf-8')
Exemple #8
0
def OpBLS_G1_IsEq(arg):
    op = json.loads(arg)
    a_x = to_int(op['a_x'])
    a_y = to_int(op['a_y'])
    b_x = to_int(op['b_x'])
    b_y = to_int(op['b_y'])

    if (a_x % MOD, a_y % MOD) == (0, 0):
        return
    if (b_x % MOD, b_y % MOD) == (0, 0):
        return

    A = [FQ(a_x), FQ(a_y), FQ.one()]
    B = [FQ(b_x), FQ(b_y), FQ.one()]

    r = json.dumps(A == B)
    return bytes(r, 'utf-8')
def test_FQ_sgn0(degree, value, expected):
    if degree == 1:
        x = FQ(value)
    elif degree == 2:
        x = FQ2([value, 0])
    elif degree == 12:
        x = FQ12([value] + [0] * 11)

    assert x.sgn0 == expected
    if value != 0:
        assert x.sgn0 != (-x).sgn0
Exemple #10
0
def decompress_G1(z: G1Compressed) -> G1Uncompressed:
    """
    Recovers x and y coordinates from the compressed point.
    """
    # b_flag == 1 indicates the infinity point
    b_flag = (z % POW_2_383) // POW_2_382
    if b_flag == 1:
        return Z1
    x = z % POW_2_381

    # Try solving y coordinate from the equation Y^2 = X^3 + b
    # using quadratic residue
    y = pow((x**3 + b.n) % q, (q + 1) // 4, q)

    if pow(y, 2, q) != (x**3 + b.n) % q:
        raise ValueError("The given point is not on G1: y**2 = x**3 + b")
    # Choose the y whose leftmost bit is equal to the a_flag
    a_flag = (z % POW_2_382) // POW_2_381
    if (y * 2) // q != a_flag:
        y = q - y
    return (FQ(x), FQ(y), FQ(1))
Exemple #11
0
def decompress_G1(z: G1Compressed) -> G1Uncompressed:
    """
    Recovers x and y coordinates from the compressed point.
    """
    c_flag, b_flag, a_flag = get_flags(z)

    # c_flag == 1 indicates the compressed form
    # MSB should be 1
    if not c_flag:
        raise ValueError("c_flag should be 1")

    is_inf_pt = is_point_at_infinity(z)

    if b_flag != is_inf_pt:
        raise ValueError("b_flag should be %d" % int(is_inf_pt))

    if is_inf_pt:
        # 3 MSBs should be 110
        if a_flag:
            raise ValueError("a point at infinity should have a_flag == 0")
        return Z1

    # Else, not point at infinity
    # 3 MSBs should be 100 or 101
    x = z % POW_2_381
    if x >= q:
        raise ValueError(
            "Point value should be less than field modulus. Got %d", x)

    # Try solving y coordinate from the equation Y^2 = X^3 + b
    # using quadratic residue
    y = pow((x**3 + b.n) % q, (q + 1) // 4, q)

    if pow(y, 2, q) != (x**3 + b.n) % q:
        raise ValueError("The given point is not on G1: y**2 = x**3 + b")
    # Choose the y whose leftmost bit is equal to the a_flag
    if (y * 2) // q != int(a_flag):
        y = q - y
    return (FQ(x), FQ(y), FQ(1))
Exemple #12
0
    if pt is None:
        return None
    x, y, z = pt
    return (FQ12([x.n] + [0] * 11), FQ12([y.n] + [0] * 11),
            FQ12([z.n] + [0] * 11))


# Check consistency of the "line function"
one, two, three = G1, double(G1), multiply(G1, 3)
negone, negtwo, negthree = (
    multiply(G1, curve_order - 1),
    multiply(G1, curve_order - 2),
    multiply(G1, curve_order - 3),
)

assert linefunc(one, two, one)[0] == FQ(0)
assert linefunc(one, two, two)[0] == FQ(0)
assert linefunc(one, two, three)[0] != FQ(0)
assert linefunc(one, two, negthree)[0] == FQ(0)
assert linefunc(one, negone, one)[0] == FQ(0)
assert linefunc(one, negone, negone)[0] == FQ(0)
assert linefunc(one, negone, two)[0] != FQ(0)
assert linefunc(one, one, one)[0] == FQ(0)
assert linefunc(one, one, two)[0] != FQ(0)
assert linefunc(one, one, negtwo)[0] == FQ(0)


# Main miller loop
def miller_loop(Q: Optimized_Point3D[FQ12],
                P: Optimized_Point3D[FQ12],
                final_exponentiate: bool = True) -> FQ12:
Exemple #13
0
    bls12_381_FQ2 as FQ2,
    bls12_381_FQ12 as FQ12,
)

from .bls12_381_field_elements import (
    field_modulus, )

curve_order = 52435875175126190479447740508185965837690552500527637822603658699938581184513

# Curve order should be prime
assert pow(2, curve_order, curve_order) == 2
# Curve order should be a factor of field_modulus**12 - 1
assert (field_modulus**12 - 1) % curve_order == 0

# Curve is y**2 = x**3 + 4
b = FQ(4)
# Twisted curve over FQ**2
b2 = FQ2((4, 4))
# Extension curve over FQ**12; same b value as over FQ
b12 = FQ12((4, ) + (0, ) * 11)

# Generator for curve over FQ
G1 = (
    FQ(3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507
       ),  # noqa: E501
    FQ(1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569
       ),  # noqa: E501
)
# Generator for twisted curve over FQ2
G2 = (
    FQ2([
Exemple #14
0
    GeneralPoint,
    Point2D,
)

from .bn128_field_elements import (
    field_modulus, )

curve_order = 21888242871839275222246405745257275088548364400416034343698204186575808495617

# Curve order should be prime
assert pow(2, curve_order, curve_order) == 2
# Curve order should be a factor of field_modulus**12 - 1
assert (field_modulus**12 - 1) % curve_order == 0

# Curve is y**2 = x**3 + 3
b = FQ(3)
# Twisted curve over FQ**2
b2 = FQ2([3, 0]) / FQ2([9, 1])
# Extension curve over FQ**12; same b value as over FQ
b12 = FQ12([3] + [0] * 11)

# Generator for curve over FQ
G1 = cast(Point2D[FQ], (FQ(1), FQ(2)))
# Generator for twisted curve over FQ2
G2 = (
    FQ2([
        10857046999023057135944570762232829481370756359578518086990519993285655852781,
        11559732032986387107991004021392285783925812861821192530917403151452391805634,
    ]),
    FQ2([
        8495653923123431417604973247489272438418190587263600148770280649306958101930,
Exemple #15
0
def test_decompress_G2_with_no_modular_square_root_found():
    with pytest.raises(ValueError,
                       match="Failed to find a modular squareroot"):
        signature_to_G2(b'\x11' * 96)


@pytest.mark.parametrize(
    'pt,on_curve,is_infinity',
    [
        # On curve points
        (G1, True, False),
        (multiply(G1, 5), True, False),
        # Infinity point but still on curve
        (Z1, True, True),
        # Not on curve
        ((FQ(5566), FQ(5566), FQ.one()), False, None),
    ])
def test_G1_compress_and_decompress_flags(pt, on_curve, is_infinity):
    assert on_curve == is_on_curve(pt, b)
    z = compress_G1(pt)
    if on_curve:
        x = z % POW_2_381
        c_flag = (z % 2**384) // POW_2_383
        b_flag = (z % POW_2_383) // POW_2_382
        a_flag = (z % POW_2_382) // POW_2_381
        assert x < q
        assert c_flag == 1
        if is_infinity:
            assert b_flag == 1
            assert a_flag == x == 0
        else:
Exemple #16
0
 def to_point(self) -> G1Uncompressed:
     x = int.from_bytes(self.value[:48], 'big')
     y = int.from_bytes(self.value[48:], 'big')
     point = FQ(x), FQ(y), FQ(1)
     return cast(G1Uncompressed, point)
from py_ecc.typing import (
    Optimized_Field,
    Optimized_Point2D,
    Optimized_Point3D,
)

field_modulus = field_properties["bn128"]["field_modulus"]
curve_order = 21888242871839275222246405745257275088548364400416034343698204186575808495617

# Curve order should be prime
assert pow(2, curve_order, curve_order) == 2
# Curve order should be a factor of field_modulus**12 - 1
assert (field_modulus**12 - 1) % curve_order == 0

# Curve is y**2 = x**3 + 3
b = FQ(3)
# Twisted curve over FQ**2
b2 = FQ2([3, 0]) / FQ2([9, 1])
# Extension curve over FQ**12; same b value as over FQ
b12 = FQ12([3] + [0] * 11)

# Generator for curve over FQ
G1 = (FQ(1), FQ(2), FQ(1))
# Generator for twisted curve over FQ2
G2 = (
    FQ2([
        10857046999023057135944570762232829481370756359578518086990519993285655852781,
        11559732032986387107991004021392285783925812861821192530917403151452391805634
    ]),
    FQ2([
        8495653923123431417604973247489272438418190587263600148770280649306958101930,
        return None
    x, y = pt
    fq12_point = (FQ12([x.n] + [0] * 11), FQ12([y.n] + [0] * 11))
    return fq12_point


# Check consistency of the "line function"
one, two, three = G1, double(G1), multiply(G1, 3)
negone, negtwo, negthree = (
    multiply(G1, curve_order - 1),
    multiply(G1, curve_order - 2),
    multiply(G1, curve_order - 3),
)


assert linefunc(one, two, one) == FQ(0)
assert linefunc(one, two, two) == FQ(0)
assert linefunc(one, two, three) != FQ(0)
assert linefunc(one, two, negthree) == FQ(0)
assert linefunc(one, negone, one) == FQ(0)
assert linefunc(one, negone, negone) == FQ(0)
assert linefunc(one, negone, two) != FQ(0)
assert linefunc(one, one, one) == FQ(0)
assert linefunc(one, one, two) != FQ(0)
assert linefunc(one, one, negtwo) == FQ(0)


# Main miller loop
def miller_loop(Q: Point2D[FQ12],
                P: Point2D[FQ12]) -> FQ12:
    if Q is None or P is None:
Exemple #19
0
 def of_hex(hexstr: str) -> G1Point:
     xxx_bytes = bytes.fromhex(hexstr[2:98])
     yyy_bytes = bytes.fromhex(hexstr[98:])
     xxx = int.from_bytes(xxx_bytes, byteorder='big')
     yyy = int.from_bytes(yyy_bytes, byteorder='big')
     return (FQ(xxx), FQ(yyy), FQ(1))
Exemple #20
0
from py_ecc.fields import optimized_bn128_FQ as FQ
from Crypto.Cipher import Salsa20
from Crypto.Hash import SHA256
from Crypto.Protocol.KDF import HKDF

H2 = (FQ2((
    9110522554455888802745409460679507850660709404525090688071718755658817738702,
    14120302265976430476300156362541817133873389322564306174224598966336605751189
)),
      FQ2((
          8015061597608194114184122605728732604411275728909990814600934336120589400179,
          21550838471174089343030649382112381550278244756451022825185015902639198926789
      )), FQ2.one())

H1 = (
    FQ(9727523064272218541460723335320998459488975639302513747055235660443850046724
       ),
    FQ(5031696974169251245229961296941447383441169981934237515842977230762345915487
       ),
    FQ(1),
)


class IntPoly:
    def __init__(self, coeffs):
        self.coeffs = [coeff % CURVE_ORDER for coeff in coeffs]

    def evaluate(self, x):
        return sum([
            coeff * pow(x, i, CURVE_ORDER)
            for i, coeff in enumerate(self.coeffs)
        ]) % CURVE_ORDER