Esempio n. 1
0
def OpBLS_G2_Add(arg):
    op = json.loads(arg)
    a_v = to_int(op['a_v'])
    a_w = to_int(op['a_w'])
    a_x = to_int(op['a_x'])
    a_y = to_int(op['a_y'])
    b_v = to_int(op['b_v'])
    b_w = to_int(op['b_w'])
    b_x = to_int(op['b_x'])
    b_y = to_int(op['b_y'])

    A = (FQ2((a_v, a_x)), FQ2((a_w, a_y)), FQ2.one())
    B = (FQ2((b_v, b_x)), FQ2((b_w, b_y)), FQ2.one())

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

    result = add(A, B)

    x = result[0] / result[2]
    y = result[1] / result[2]

    result = [[str(x.coeffs[0]), str(y.coeffs[0])],
              [str(x.coeffs[1]), str(y.coeffs[1])]]

    r = json.dumps(result)
    return bytes(r, 'utf-8')
Esempio n. 2
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')
Esempio n. 3
0
def decompress_G2(p: G2Compressed) -> G2Uncompressed:
    """
    Recovers x and y coordinates from the compressed point (z1, z2).
    """
    z1, z2 = p

    # b_flag == 1 indicates the infinity point
    b_flag1 = (z1 % POW_2_383) // POW_2_382
    if b_flag1 == 1:
        return Z2

    x1 = z1 % POW_2_381
    x2 = z2
    # x1 is the imaginary part, x2 is the real part
    x = FQ2([x2, x1])
    y = modular_squareroot_in_FQ2(x**3 + b2)
    if y is None:
        raise ValueError("Failed to find a modular squareroot")

    # Choose the y whose leftmost bit of the imaginary part is equal to the a_flag1
    # If y_im happens to be zero, then use the bit of y_re
    a_flag1 = (z1 % POW_2_382) // POW_2_381
    y_re, y_im = y.coeffs
    if (y_im > 0 and
        (y_im * 2) // q != a_flag1) or (y_im == 0 and
                                        (y_re * 2) // q != a_flag1):
        y = FQ2((y * -1).coeffs)

    if not is_on_curve((x, y, FQ2([1, 0])), b2):
        raise ValueError(
            "The given point is not on the twisted curve over FQ**2")
    return (x, y, FQ2([1, 0]))
Esempio n. 4
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')
Esempio n. 5
0
def test_hash_to_G2():
    message_hash = b'\x12' * 32

    domain_1 = 1
    domain_in_bytes = domain_1.to_bytes(8, 'big')
    result_1 = hash_to_G2(message_hash, domain_in_bytes)
    assert is_on_curve(result_1, b2)
Esempio n. 6
0
def compress_G2(pt: G2Uncompressed) -> G2Compressed:
    """
    The compressed point (z1, z2) has the bit order:
    z1: (c_flag1, b_flag1, a_flag1, x1)
    z2: (c_flag2, b_flag2, a_flag2, x2)
    where
    - c_flag1 is always set to 1
    - b_flag1 indicates infinity when set to 1
    - a_flag1 helps determine the y-coordinate when decompressing,
    - a_flag2, b_flag2, and c_flag2 are always set to 0
    """
    if not is_on_curve(pt, b2):
        raise ValueError(
            "The given point is not on the twisted curve over FQ**2")
    if is_inf(pt):
        return G2Compressed((POW_2_383 + POW_2_382, 0))
    x, y = normalize(pt)
    x_re, x_im = x.coeffs
    y_re, y_im = y.coeffs
    # Record the leftmost bit of y_im to the a_flag1
    # If y_im happens to be zero, then use the bit of y_re
    a_flag1 = (y_im * 2) // q if y_im > 0 else (y_re * 2) // q

    # Imaginary part of x goes to z1, real part goes to z2
    # c_flag1 = 1, b_flag1 = 0
    z1 = x_im + a_flag1 * POW_2_381 + POW_2_383
    # a_flag2 = b_flag2 = c_flag2 = 0
    z2 = x_re
    return G2Compressed((z1, z2))
Esempio n. 7
0
def mk_generator_points(count):
    points = []
    x = b.FQ(1)
    while len(points) < count:
        y = (x**3 + b.b)**((b.field_modulus + 1) // 4)
        if b.is_on_curve((x, y, b.FQ(1)), b.b):
            points.append(b.multiply((x, y, b.FQ(1)), BLS12_381_COFACTOR))
        x += b.FQ(1)
    return points
Esempio n. 8
0
def test_hash_to_G2(msg, x, y, H):
    point = hash_to_G2(msg, DST, H)
    assert is_on_curve(point, b2)

    # Affine
    result_x = point[0] / point[2]  # X / Z
    result_y = point[1] / point[2]  # Y / Z

    assert x == result_x
    assert y == result_y
Esempio n. 9
0
def decompress_G2(p: G2Compressed) -> G2Uncompressed:
    """
    Recovers x and y coordinates from the compressed point (z1, z2).
    """
    z1, z2 = p
    c_flag1, b_flag1, a_flag1 = get_flags(z1)

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

    is_inf_pt = is_point_at_infinity(z1, z2)

    if b_flag1 != 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_flag1:
            raise ValueError("a point at infinity should have a_flag == 0")
        return Z2

    # Else, not point at infinity
    # 3 MSBs should be 100 or 101
    x1 = z1 % POW_2_381
    # Ensure that x1 is less than the field modulus.
    if x1 >= q:
        raise ValueError("x1 value should be less than field modulus. Got %d",
                         x1)

    # Ensure that z2 is less than the field modulus.
    if z2 >= q:
        raise ValueError(
            "z2 point value should be less than field modulus. Got %d", z2)

    x2 = z2
    # x1 is the imaginary part, x2 is the real part
    x = FQ2([x2, x1])
    y = modular_squareroot_in_FQ2(x**3 + b2)
    if y is None:
        raise ValueError("Failed to find a modular squareroot")

    # Choose the y whose leftmost bit of the imaginary part is equal to the a_flag1
    # If y_im happens to be zero, then use the bit of y_re
    y_re, y_im = y.coeffs
    if ((y_im > 0 and (y_im * 2) // q != int(a_flag1))
            or (y_im == 0 and (y_re * 2) // q != int(a_flag1))):
        y = FQ2((y * -1).coeffs)

    if not is_on_curve((x, y, FQ2([1, 0])), b2):
        raise ValueError(
            "The given point is not on the twisted curve over FQ**2")
    return (x, y, FQ2([1, 0]))
Esempio n. 10
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')
Esempio n. 11
0
def OpBLS_IsG2OnCurve(arg):
    op = json.loads(arg)
    v = to_int(op['g2_v'])
    w = to_int(op['g2_w'])
    x = to_int(op['g2_x'])
    y = to_int(op['g2_y'])

    g2 = (FQ2((v, x)), FQ2((w, y)), FQ2.one())

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

    r = json.dumps(is_on_curve(g2, b2) and subgroup_check(g2))
    return bytes(r, 'utf-8')
Esempio n. 12
0
def decompress_G2(p: Tuple[int, int]) -> Tuple[FQP, FQP, FQP]:
    x1 = p[0] % 2**383
    y1_mod_2 = p[0] // 2**383
    x2 = p[1]
    x = FQ2([x1, x2])
    if x == FQ2([0, 0]):
        return FQ2([1, 0]), FQ2([1, 0]), FQ2([0, 0])
    y = modular_squareroot(x**3 + b2)
    if y.coeffs[0] % 2 != y1_mod_2:
        y = FQ2((y * -1).coeffs)
    if not is_on_curve((x, y, FQ2([1, 0])), b2):
        raise ValueError(
            "The given point is not on the twisted curve over FQ**2")
    return x, y, FQ2([1, 0])
Esempio n. 13
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')
Esempio n. 14
0
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:
            assert b_flag == 0
            pt_x, pt_y = normalize(pt)
            assert a_flag == (pt_y.n * 2) // q
            assert x == pt_x.n
        # Correct flags should decompress correct x, y
        normalize(decompress_G1(z)) == normalize(pt)
    else:
        with pytest.raises(ValueError):
            decompress_G1(z)
Esempio n. 15
0
 def is_on_curve(xxx: G1Point) -> bool:
     return bls12_381.is_on_curve(xxx, bls12_381.b)
Esempio n. 16
0
def compress_G2(pt: Tuple[FQP, FQP, FQP]) -> Tuple[int, int]:
    if not is_on_curve(pt, b2):
        raise ValueError(
            "The given point is not on the twisted curve over FQ**2")
    x, y = normalize(pt)
    return (int(x.coeffs[0] + 2**383 * (y.coeffs[0] % 2)), int(x.coeffs[1]))
Esempio n. 17
0
def test_hash_to_G2():
    message = b'helloworld'

    domain_1 = 1
    result_1 = hash_to_G2(message, domain_1)
    assert is_on_curve(result_1, b2)
Esempio n. 18
0
def test_hash_to_G2():
    message_hash = b'\x12' * 32

    domain_1 = 1
    result_1 = hash_to_G2(message_hash, domain_1)
    assert is_on_curve(result_1, b2)