2

Etherum can verify BLS signatures, In this answer Does Ethereum support pairing operations?

There is an example of how to verify BLS in solidity. However, when I tried to test the code in remix, Update: Here is the whole contract

           pragma solidity ^0.4.14;

/*
   Example of how to verify BLS signatures and BGLS aggregate signatures in 
     Ethereum.

     Signatures are generated using https://github.com/Project-Arda/bgls
       Code is based on https://github.com/jstoxrocky/zksnarks_example
                */

   contract BLSExample {
      struct G1Point {
     uint X;
      uint Y;
     }
// Encoding of field elements is: X[0] * z + X[1]
struct G2Point {
    uint[2] X;
    uint[2] Y;
}

/// @return the generator of G1
function P1() internal returns (G1Point) {
    return G1Point(1, 2);
}

/// @return the generator of G2
function P2() internal returns (G2Point) {
    return G2Point(
        [11559732032986387107991004021392285783925812861821192530917403151452391805634,
        10857046999023057135944570762232829481370756359578518086990519993285655852781],

        [4082367875863433681332203403145435568316851327593401208105741076214120093531,
        8495653923123431417604973247489272438418190587263600148770280649306958101930]
    );
}

//Example of BLS signature verification
function verifyBLSTest() returns (bool) {

    bytes memory message = hex"7b0a2020226f70656e223a207b0a20202020227072696365223a2039353931372c0a202020202274696d65223a207b0a20202020202022756e6978223a20313438333134323430302c0a2020202020202269736f223a2022323031362d31322d33315430303a30303a30302e3030305a220a202020207d0a20207d2c0a202022636c6f7365223a207b0a20202020227072696365223a2039363736302c0a202020202274696d65223a207b0a20202020202022756e6978223a20313438333232383830302c0a2020202020202269736f223a2022323031372d30312d30315430303a30303a30302e3030305a220a202020207d0a20207d2c0a2020226c6f6f6b7570223a207b0a20202020227072696365223a2039363736302c0a20202020226b223a20312c0a202020202274696d65223a207b0a20202020202022756e6978223a20313438333232383830302c0a2020202020202269736f223a2022323031372d30312d30315430303a30303a30302e3030305a220a202020207d0a20207d0a7d0a6578616d706c652e636f6d2f6170692f31";

    G1Point memory signature = G1Point(11181692345848957662074290878138344227085597134981019040735323471731897153462, 6479746447046570360435714249272776082787932146211764251347798668447381926167);

    G2Point memory v = G2Point(
        [18523194229674161632574346342370534213928970227736813349975332190798837787897, 5725452645840548248571879966249653216818629536104756116202892528545334967238],
        [3816656720215352836236372430537606984911914992659540439626020770732736710924, 677280212051826798882467475639465784259337739185938192379192340908771705870]
    );

    G1Point memory h = hashToG1(message);

    return pairing2(negate(signature), P2(), h, v);
}

//Example of BGLS signature verification with 2 signers
//Note that the messages differ in their last character.
function verifyBGLS2() returns (bool) {

    uint numberOfSigners = 2;

    G1Point memory signature = G1Point(7985250684665362734034207174567341000146996823387166378141631317099216977152, 5471024627060516972461571110176333017668072838695251726406965080926450112048);

    bytes memory message0 = hex"7b0a2020226f70656e223a207b0a20202020227072696365223a2039353931372c0a202020202274696d65223a207b0a20202020202022756e6978223a20313438333134323430302c0a2020202020202269736f223a2022323031362d31322d33315430303a30303a30302e3030305a220a202020207d0a20207d2c0a202022636c6f7365223a207b0a20202020227072696365223a2039363736302c0a202020202274696d65223a207b0a20202020202022756e6978223a20313438333232383830302c0a2020202020202269736f223a2022323031372d30312d30315430303a30303a30302e3030305a220a202020207d0a20207d2c0a2020226c6f6f6b7570223a207b0a20202020227072696365223a2039363736302c0a20202020226b223a20312c0a202020202274696d65223a207b0a20202020202022756e6978223a20313438333232383830302c0a2020202020202269736f223a2022323031372d30312d30315430303a30303a30302e3030305a220a202020207d0a20207d0a7d0a6578616d706c652e636f6d2f6170692f30";
    bytes memory message1 = hex"7b0a2020226f70656e223a207b0a20202020227072696365223a2039353931372c0a202020202274696d65223a207b0a20202020202022756e6978223a20313438333134323430302c0a2020202020202269736f223a2022323031362d31322d33315430303a30303a30302e3030305a220a202020207d0a20207d2c0a202022636c6f7365223a207b0a20202020227072696365223a2039363736302c0a202020202274696d65223a207b0a20202020202022756e6978223a20313438333232383830302c0a2020202020202269736f223a2022323031372d30312d30315430303a30303a30302e3030305a220a202020207d0a20207d2c0a2020226c6f6f6b7570223a207b0a20202020227072696365223a2039363736302c0a20202020226b223a20312c0a202020202274696d65223a207b0a20202020202022756e6978223a20313438333232383830302c0a2020202020202269736f223a2022323031372d30312d30315430303a30303a30302e3030305a220a202020207d0a20207d0a7d0a6578616d706c652e636f6d2f6170692f31";

    G2Point memory v0 = G2Point(
        [15516709285352539082439213720585739724329002971882390582209636960597958801449, 19324541677661060388134143597417835654030498723817274130329567224531700170734],
        [16550775633156536193089672538964908973667410921848053632462693002610771214528, 10154483139478025296468271477739414260393126999813603835827647034319242387010]
    );

    G2Point memory v1 = G2Point(
        [14125383697019450293340447180826714775062600193406387386692146468060627933203, 10886345395648455940547500614900453787797209052692168129177801883734751834552],
        [13494666809312056575532152175382485778895768300692817869062640713829304801648, 10580958449683540742032499469496205826101096579572266360455646078388895706251]
    );

    G1Point memory h0 = hashToG1(message0);
    G1Point memory h1 = hashToG1(message1);

    G1Point[] memory a = new G1Point[](numberOfSigners + 1);
    G2Point[] memory b = new G2Point[](numberOfSigners + 1);
    a[0] = negate(signature);
    a[1] = h0;
    a[2] = h1;
    b[0] = P2();
    b[1] = v0;
    b[2] = v1;

    return pairing(a, b);
}

//Example of BGLS signature verification with 3 signers
//Note that the messages differ in their last character.
function verifyBGLS3() returns (bool) {

    uint numberOfSigners = 3;

    G1Point memory signature = G1Point(385846518441062319503502284295243290270560187383398932887791670182362540842, 19731933537428695151702009864745685458233056709189425720845387511061953267292);

    bytes memory message0 = hex"7b0a2020226f70656e223a207b0a20202020227072696365223a2039353931372c0a202020202274696d65223a207b0a20202020202022756e6978223a20313438333134323430302c0a2020202020202269736f223a2022323031362d31322d33315430303a30303a30302e3030305a220a202020207d0a20207d2c0a202022636c6f7365223a207b0a20202020227072696365223a2039363736302c0a202020202274696d65223a207b0a20202020202022756e6978223a20313438333232383830302c0a2020202020202269736f223a2022323031372d30312d30315430303a30303a30302e3030305a220a202020207d0a20207d2c0a2020226c6f6f6b7570223a207b0a20202020227072696365223a2039363736302c0a20202020226b223a20312c0a202020202274696d65223a207b0a20202020202022756e6978223a20313438333232383830302c0a2020202020202269736f223a2022323031372d30312d30315430303a30303a30302e3030305a220a202020207d0a20207d0a7d0a6578616d706c652e636f6d2f6170692f30";
    bytes memory message1 = hex"7b0a2020226f70656e223a207b0a20202020227072696365223a2039353931372c0a202020202274696d65223a207b0a20202020202022756e6978223a20313438333134323430302c0a2020202020202269736f223a2022323031362d31322d33315430303a30303a30302e3030305a220a202020207d0a20207d2c0a202022636c6f7365223a207b0a20202020227072696365223a2039363736302c0a202020202274696d65223a207b0a20202020202022756e6978223a20313438333232383830302c0a2020202020202269736f223a2022323031372d30312d30315430303a30303a30302e3030305a220a202020207d0a20207d2c0a2020226c6f6f6b7570223a207b0a20202020227072696365223a2039363736302c0a20202020226b223a20312c0a202020202274696d65223a207b0a20202020202022756e6978223a20313438333232383830302c0a2020202020202269736f223a2022323031372d30312d30315430303a30303a30302e3030305a220a202020207d0a20207d0a7d0a6578616d706c652e636f6d2f6170692f31";
    bytes memory message2 = hex"7b0a2020226f70656e223a207b0a20202020227072696365223a2039353931372c0a202020202274696d65223a207b0a20202020202022756e6978223a20313438333134323430302c0a2020202020202269736f223a2022323031362d31322d33315430303a30303a30302e3030305a220a202020207d0a20207d2c0a202022636c6f7365223a207b0a20202020227072696365223a2039363736302c0a202020202274696d65223a207b0a20202020202022756e6978223a20313438333232383830302c0a2020202020202269736f223a2022323031372d30312d30315430303a30303a30302e3030305a220a202020207d0a20207d2c0a2020226c6f6f6b7570223a207b0a20202020227072696365223a2039363736302c0a20202020226b223a20312c0a202020202274696d65223a207b0a20202020202022756e6978223a20313438333232383830302c0a2020202020202269736f223a2022323031372d30312d30315430303a30303a30302e3030305a220a202020207d0a20207d0a7d0a6578616d706c652e636f6d2f6170692f32";

    G2Point memory v0 = G2Point(
        [1787282038370667094324364195810339512415273589223814213215040505578200405366, 414568866548933554513940840943382696902163788831396286279770126458218272940],
        [6560020551439455112781785895092032589010633560844445112872109862153018855017, 19411093226570397520343120724285433000937737461010544490862811136406407315543]
    );

    G2Point memory v1 = G2Point(
        [14831125462625540363404323739936082597729714855858291605999144010730542058037, 8342129546329626371616639780890580451066604883761980695690870205390518348707],
        [808186590373043742842665711030588185456231663895663328011864547134240543671, 1856705676948889458735296604372981546875220644939188415241687241562401814459]
    );

    G2Point memory v2 = G2Point(
        [12507030828714819990408995725310388936101611986473926829733453468215798265704, 16402225253711577242710704509153100189802817297679524801952098990526969620006],
        [18717845356690477533392378472300056893077745517009561191866660997312973511514, 20124563173642533900823905467925868861151292863229012000403558815142682516349]
    );

    G1Point memory h0 = hashToG1(message0);
    G1Point memory h1 = hashToG1(message1);
    G1Point memory h2 = hashToG1(message2);

    G1Point[] memory a = new G1Point[](numberOfSigners + 1);
    G2Point[] memory b = new G2Point[](numberOfSigners + 1);
    a[0] = negate(signature);
    a[1] = h0;
    a[2] = h1;
    a[3] = h2;
    b[0] = P2();
    b[1] = v0;
    b[2] = v1;
    b[3] = v2;

    return pairing(a, b);
}

/// @return the result of computing the pairing check
/// e(p1[0], p2[0]) *  .... * e(p1[n], p2[n]) == 1
/// For example pairing([P1(), P1().negate()], [P2(), P2()]) should
/// return true.
function pairing(G1Point[] p1, G2Point[] p2) internal returns (bool) {
    require(p1.length == p2.length);
    uint elements = p1.length;
    uint inputSize = elements * 6;
    uint[] memory input = new uint[](inputSize);

    for (uint i = 0; i < elements; i++)
    {
        input[i * 6 + 0] = p1[i].X;
        input[i * 6 + 1] = p1[i].Y;
        input[i * 6 + 2] = p2[i].X[0];
        input[i * 6 + 3] = p2[i].X[1];
        input[i * 6 + 4] = p2[i].Y[0];
        input[i * 6 + 5] = p2[i].Y[1];
    }

    uint[1] memory out;
    bool success;

    assembly {
        success := call(sub(gas, 2000), 8, 0, add(input, 0x20), mul(inputSize, 0x20), out, 0x20)
    // Use "invalid" to make gas estimation work
        switch success case 0 {invalid}
    }
    require(success);
    return out[0] != 0;
}

/// Convenience method for a pairing check for two pairs.
function pairing2(G1Point a1, G2Point a2, G1Point b1, G2Point b2) internal returns (bool) {
    G1Point[] memory p1 = new G1Point[](2);
    G2Point[] memory p2 = new G2Point[](2);
    p1[0] = a1;
    p1[1] = b1;
    p2[0] = a2;
    p2[1] = b2;
    return pairing(p1, p2);
}

function hashToG1(bytes message) internal returns (G1Point) {
    uint256 h = uint256(keccak256(message));
    return mul(P1(), h);
}

function modPow(uint256 base, uint256 exponent, uint256 modulus) internal returns (uint256) {
    uint256[6] memory input = [32, 32, 32, base, exponent, modulus];
    uint256[1] memory result;
    assembly {
        if iszero(call(not(0), 0x05, 0, input, 0xc0, result, 0x20)) {
            revert(0, 0)
        }
    }
    return result[0];
}

/// @return the negation of p, i.e. p.add(p.negate()) should be zero.
function negate(G1Point p) internal returns (G1Point) {
    // The prime q in the base field F_q for G1
    uint q = 21888242871839275222246405745257275088696311157297823662689037894645226208583;
    if (p.X == 0 && p.Y == 0)
        return G1Point(0, 0);
    return G1Point(p.X, q - (p.Y % q));
}

/// @return the sum of two points of G1
function add(G1Point p1, G1Point p2) internal returns (G1Point r) {
    uint[4] memory input;
    input[0] = p1.X;
    input[1] = p1.Y;
    input[2] = p2.X;
    input[3] = p2.Y;
    bool success;
    assembly {
        success := call(sub(gas, 2000), 6, 0, input, 0xc0, r, 0x60)
    // Use "invalid" to make gas estimation work
        switch success case 0 {invalid}
    }
    require(success);
}
/// @return the product of a point on G1 and a scalar, i.e.
/// p == p.mul(1) and p.add(p) == p.mul(2) for all points p.
function mul(G1Point p, uint s) internal returns (G1Point r) {
    uint[3] memory input;
    input[0] = p.X;
    input[1] = p.Y;
    input[2] = s;
    bool success;
    assembly {
        success := call(sub(gas, 2000), 7, 0, input, 0x80, r, 0x60)
    // Use "invalid" to make gas estimation work
        switch success case 0 {invalid}
    }
    require(success);
}

}

I got the following 2 errors in remix:

browser/Pairing.sol:187:13: ParserError: Literal, identifier or instruction 
expected. if iszero(call(not(0), 0x05, 0, input, 0xc0, result, 0x20)) {

and

 browser/Pairing.sol:187:16: ParserError: Expected token LParen got 
 'Identifier'  if iszero(call(not(0), 0x05, 0, input, 0xc0, result, 0x20)) { 
  ^

Could you please help me figure out how to solve these errors ?

The original code contract is available on github https://gist.github.com/BjornvdLaan/ca6dd4e3993e1ef392f363ec27fe74c4

3

Change the compiler version in Remix. If you set 0.4.24 or 0.4.25 (for example) the code works with some warnings. You need to make some modifications in the code if you want to use the compiler version 0.5.0 or later.

Modified code for 0.5.x (with warnings):

pragma solidity ^0.5.0;

/*
   Example of how to verify BLS signatures and BGLS aggregate signatures in 
     Ethereum.

     Signatures are generated using https://github.com/Project-Arda/bgls
       Code is based on https://github.com/jstoxrocky/zksnarks_example
                */

   contract BLSExample {
      struct G1Point {
     uint X;
      uint Y;
     }
// Encoding of field elements is: X[0] * z + X[1]
struct G2Point {
    uint[2] X;
    uint[2] Y;
}

/// @return the generator of G1
function P1() internal returns (G1Point memory) {
    return G1Point(1, 2);
}

/// @return the generator of G2
function P2() internal returns (G2Point memory) {
    return G2Point(
        [11559732032986387107991004021392285783925812861821192530917403151452391805634,
        10857046999023057135944570762232829481370756359578518086990519993285655852781],

        [4082367875863433681332203403145435568316851327593401208105741076214120093531,
        8495653923123431417604973247489272438418190587263600148770280649306958101930]
    );
}

//Example of BLS signature verification
function verifyBLSTest() public returns (bool) {

    bytes memory message = hex"7b0a2020226f70656e223a207b0a20202020227072696365223a2039353931372c0a202020202274696d65223a207b0a20202020202022756e6978223a20313438333134323430302c0a2020202020202269736f223a2022323031362d31322d33315430303a30303a30302e3030305a220a202020207d0a20207d2c0a202022636c6f7365223a207b0a20202020227072696365223a2039363736302c0a202020202274696d65223a207b0a20202020202022756e6978223a20313438333232383830302c0a2020202020202269736f223a2022323031372d30312d30315430303a30303a30302e3030305a220a202020207d0a20207d2c0a2020226c6f6f6b7570223a207b0a20202020227072696365223a2039363736302c0a20202020226b223a20312c0a202020202274696d65223a207b0a20202020202022756e6978223a20313438333232383830302c0a2020202020202269736f223a2022323031372d30312d30315430303a30303a30302e3030305a220a202020207d0a20207d0a7d0a6578616d706c652e636f6d2f6170692f31";

    G1Point memory signature = G1Point(11181692345848957662074290878138344227085597134981019040735323471731897153462, 6479746447046570360435714249272776082787932146211764251347798668447381926167);

    G2Point memory v = G2Point(
        [18523194229674161632574346342370534213928970227736813349975332190798837787897, 5725452645840548248571879966249653216818629536104756116202892528545334967238],
        [3816656720215352836236372430537606984911914992659540439626020770732736710924, 677280212051826798882467475639465784259337739185938192379192340908771705870]
    );

    G1Point memory h = hashToG1(message);

    return pairing2(negate(signature), P2(), h, v);
}

//Example of BGLS signature verification with 2 signers
//Note that the messages differ in their last character.
function verifyBGLS2() public returns (bool) {

    uint numberOfSigners = 2;

    G1Point memory signature = G1Point(7985250684665362734034207174567341000146996823387166378141631317099216977152, 5471024627060516972461571110176333017668072838695251726406965080926450112048);

    bytes memory message0 = hex"7b0a2020226f70656e223a207b0a20202020227072696365223a2039353931372c0a202020202274696d65223a207b0a20202020202022756e6978223a20313438333134323430302c0a2020202020202269736f223a2022323031362d31322d33315430303a30303a30302e3030305a220a202020207d0a20207d2c0a202022636c6f7365223a207b0a20202020227072696365223a2039363736302c0a202020202274696d65223a207b0a20202020202022756e6978223a20313438333232383830302c0a2020202020202269736f223a2022323031372d30312d30315430303a30303a30302e3030305a220a202020207d0a20207d2c0a2020226c6f6f6b7570223a207b0a20202020227072696365223a2039363736302c0a20202020226b223a20312c0a202020202274696d65223a207b0a20202020202022756e6978223a20313438333232383830302c0a2020202020202269736f223a2022323031372d30312d30315430303a30303a30302e3030305a220a202020207d0a20207d0a7d0a6578616d706c652e636f6d2f6170692f30";
    bytes memory message1 = hex"7b0a2020226f70656e223a207b0a20202020227072696365223a2039353931372c0a202020202274696d65223a207b0a20202020202022756e6978223a20313438333134323430302c0a2020202020202269736f223a2022323031362d31322d33315430303a30303a30302e3030305a220a202020207d0a20207d2c0a202022636c6f7365223a207b0a20202020227072696365223a2039363736302c0a202020202274696d65223a207b0a20202020202022756e6978223a20313438333232383830302c0a2020202020202269736f223a2022323031372d30312d30315430303a30303a30302e3030305a220a202020207d0a20207d2c0a2020226c6f6f6b7570223a207b0a20202020227072696365223a2039363736302c0a20202020226b223a20312c0a202020202274696d65223a207b0a20202020202022756e6978223a20313438333232383830302c0a2020202020202269736f223a2022323031372d30312d30315430303a30303a30302e3030305a220a202020207d0a20207d0a7d0a6578616d706c652e636f6d2f6170692f31";

    G2Point memory v0 = G2Point(
        [15516709285352539082439213720585739724329002971882390582209636960597958801449, 19324541677661060388134143597417835654030498723817274130329567224531700170734],
        [16550775633156536193089672538964908973667410921848053632462693002610771214528, 10154483139478025296468271477739414260393126999813603835827647034319242387010]
    );

    G2Point memory v1 = G2Point(
        [14125383697019450293340447180826714775062600193406387386692146468060627933203, 10886345395648455940547500614900453787797209052692168129177801883734751834552],
        [13494666809312056575532152175382485778895768300692817869062640713829304801648, 10580958449683540742032499469496205826101096579572266360455646078388895706251]
    );

    G1Point memory h0 = hashToG1(message0);
    G1Point memory h1 = hashToG1(message1);

    G1Point[] memory a = new G1Point[](numberOfSigners + 1);
    G2Point[] memory b = new G2Point[](numberOfSigners + 1);
    a[0] = negate(signature);
    a[1] = h0;
    a[2] = h1;
    b[0] = P2();
    b[1] = v0;
    b[2] = v1;

    return pairing(a, b);
}

//Example of BGLS signature verification with 3 signers
//Note that the messages differ in their last character.
function verifyBGLS3() public returns (bool) {

    uint numberOfSigners = 3;

    G1Point memory signature = G1Point(385846518441062319503502284295243290270560187383398932887791670182362540842, 19731933537428695151702009864745685458233056709189425720845387511061953267292);

    bytes memory message0 = hex"7b0a2020226f70656e223a207b0a20202020227072696365223a2039353931372c0a202020202274696d65223a207b0a20202020202022756e6978223a20313438333134323430302c0a2020202020202269736f223a2022323031362d31322d33315430303a30303a30302e3030305a220a202020207d0a20207d2c0a202022636c6f7365223a207b0a20202020227072696365223a2039363736302c0a202020202274696d65223a207b0a20202020202022756e6978223a20313438333232383830302c0a2020202020202269736f223a2022323031372d30312d30315430303a30303a30302e3030305a220a202020207d0a20207d2c0a2020226c6f6f6b7570223a207b0a20202020227072696365223a2039363736302c0a20202020226b223a20312c0a202020202274696d65223a207b0a20202020202022756e6978223a20313438333232383830302c0a2020202020202269736f223a2022323031372d30312d30315430303a30303a30302e3030305a220a202020207d0a20207d0a7d0a6578616d706c652e636f6d2f6170692f30";
    bytes memory message1 = hex"7b0a2020226f70656e223a207b0a20202020227072696365223a2039353931372c0a202020202274696d65223a207b0a20202020202022756e6978223a20313438333134323430302c0a2020202020202269736f223a2022323031362d31322d33315430303a30303a30302e3030305a220a202020207d0a20207d2c0a202022636c6f7365223a207b0a20202020227072696365223a2039363736302c0a202020202274696d65223a207b0a20202020202022756e6978223a20313438333232383830302c0a2020202020202269736f223a2022323031372d30312d30315430303a30303a30302e3030305a220a202020207d0a20207d2c0a2020226c6f6f6b7570223a207b0a20202020227072696365223a2039363736302c0a20202020226b223a20312c0a202020202274696d65223a207b0a20202020202022756e6978223a20313438333232383830302c0a2020202020202269736f223a2022323031372d30312d30315430303a30303a30302e3030305a220a202020207d0a20207d0a7d0a6578616d706c652e636f6d2f6170692f31";
    bytes memory message2 = hex"7b0a2020226f70656e223a207b0a20202020227072696365223a2039353931372c0a202020202274696d65223a207b0a20202020202022756e6978223a20313438333134323430302c0a2020202020202269736f223a2022323031362d31322d33315430303a30303a30302e3030305a220a202020207d0a20207d2c0a202022636c6f7365223a207b0a20202020227072696365223a2039363736302c0a202020202274696d65223a207b0a20202020202022756e6978223a20313438333232383830302c0a2020202020202269736f223a2022323031372d30312d30315430303a30303a30302e3030305a220a202020207d0a20207d2c0a2020226c6f6f6b7570223a207b0a20202020227072696365223a2039363736302c0a20202020226b223a20312c0a202020202274696d65223a207b0a20202020202022756e6978223a20313438333232383830302c0a2020202020202269736f223a2022323031372d30312d30315430303a30303a30302e3030305a220a202020207d0a20207d0a7d0a6578616d706c652e636f6d2f6170692f32";

    G2Point memory v0 = G2Point(
        [1787282038370667094324364195810339512415273589223814213215040505578200405366, 414568866548933554513940840943382696902163788831396286279770126458218272940],
        [6560020551439455112781785895092032589010633560844445112872109862153018855017, 19411093226570397520343120724285433000937737461010544490862811136406407315543]
    );

    G2Point memory v1 = G2Point(
        [14831125462625540363404323739936082597729714855858291605999144010730542058037, 8342129546329626371616639780890580451066604883761980695690870205390518348707],
        [808186590373043742842665711030588185456231663895663328011864547134240543671, 1856705676948889458735296604372981546875220644939188415241687241562401814459]
    );

    G2Point memory v2 = G2Point(
        [12507030828714819990408995725310388936101611986473926829733453468215798265704, 16402225253711577242710704509153100189802817297679524801952098990526969620006],
        [18717845356690477533392378472300056893077745517009561191866660997312973511514, 20124563173642533900823905467925868861151292863229012000403558815142682516349]
    );

    G1Point memory h0 = hashToG1(message0);
    G1Point memory h1 = hashToG1(message1);
    G1Point memory h2 = hashToG1(message2);

    G1Point[] memory a = new G1Point[](numberOfSigners + 1);
    G2Point[] memory b = new G2Point[](numberOfSigners + 1);
    a[0] = negate(signature);
    a[1] = h0;
    a[2] = h1;
    a[3] = h2;
    b[0] = P2();
    b[1] = v0;
    b[2] = v1;
    b[3] = v2;

    return pairing(a, b);
}

/// @return the result of computing the pairing check
/// e(p1[0], p2[0]) *  .... * e(p1[n], p2[n]) == 1
/// For example pairing([P1(), P1().negate()], [P2(), P2()]) should
/// return true.
function pairing(G1Point[] memory p1, G2Point[] memory p2) internal returns (bool) {
    require(p1.length == p2.length);
    uint elements = p1.length;
    uint inputSize = elements * 6;
    uint[] memory input = new uint[](inputSize);

    for (uint i = 0; i < elements; i++)
    {
        input[i * 6 + 0] = p1[i].X;
        input[i * 6 + 1] = p1[i].Y;
        input[i * 6 + 2] = p2[i].X[0];
        input[i * 6 + 3] = p2[i].X[1];
        input[i * 6 + 4] = p2[i].Y[0];
        input[i * 6 + 5] = p2[i].Y[1];
    }

    uint[1] memory out;
    bool success;

    assembly {
        success := call(sub(gas, 2000), 8, 0, add(input, 0x20), mul(inputSize, 0x20), out, 0x20)
    // Use "invalid" to make gas estimation work
        switch success case 0 {invalid()}
    }
    require(success);
    return out[0] != 0;
}

/// Convenience method for a pairing check for two pairs.
function pairing2(G1Point memory a1, G2Point memory a2, G1Point memory b1, G2Point memory b2) internal returns (bool) {
    G1Point[] memory p1 = new G1Point[](2);
    G2Point[] memory p2 = new G2Point[](2);
    p1[0] = a1;
    p1[1] = b1;
    p2[0] = a2;
    p2[1] = b2;
    return pairing(p1, p2);
}

function hashToG1(bytes memory message) internal returns (G1Point memory) {
    uint256 h = uint256(keccak256(message));
    return mul(P1(), h);
}

function modPow(uint256 base, uint256 exponent, uint256 modulus) internal returns (uint256) {
    uint256[6] memory input = [32, 32, 32, base, exponent, modulus];
    uint256[1] memory result;
    assembly {
        if iszero(call(not(0), 0x05, 0, input, 0xc0, result, 0x20)) {
            revert(0, 0)
        }
    }
    return result[0];
}

/// @return the negation of p, i.e. p.add(p.negate()) should be zero.
function negate(G1Point memory p) internal returns (G1Point memory) {
    // The prime q in the base field F_q for G1
    uint q = 21888242871839275222246405745257275088696311157297823662689037894645226208583;
    if (p.X == 0 && p.Y == 0)
        return G1Point(0, 0);
    return G1Point(p.X, q - (p.Y % q));
}

/// @return the sum of two points of G1
function add(G1Point memory p1, G1Point memory p2) internal returns (G1Point memory r) {
    uint[4] memory input;
    input[0] = p1.X;
    input[1] = p1.Y;
    input[2] = p2.X;
    input[3] = p2.Y;
    bool success;
    assembly {
        success := call(sub(gas, 2000), 6, 0, input, 0xc0, r, 0x60)
    // Use "invalid" to make gas estimation work
        switch success case 0 {invalid()}
    }
    require(success);
}
/// @return the product of a point on G1 and a scalar, i.e.
/// p == p.mul(1) and p.add(p) == p.mul(2) for all points p.
function mul(G1Point memory p, uint s) internal returns (G1Point memory r) {
    uint[3] memory input;
    input[0] = p.X;
    input[1] = p.Y;
    input[2] = s;
    bool success;
    assembly {
        success := call(sub(gas, 2000), 7, 0, input, 0x80, r, 0x60)
    // Use "invalid" to make gas estimation work
        switch success case 0 {invalid()}
    }
    require(success);
    }
}
  • I changed it but I still does not work. I used 0.5.9 but I got the following error. browser/Pairing.sol:1:1: ParserError: Source file requires different compiler version (current compiler is 0.5.9+commit.e560f70d.Emscripten.clang - note that nightly builds are considered to be strictly less than the released version pragma solidity ^0.4.14; ^----------------------^ – Mohamed Jun 10 '19 at 9:03
  • Answer update with the code for compiler version 0.5.9. – alberto Jun 10 '19 at 9:15
  • Thanks a lot. Could you tell me how u can modify contracts so it can work fine with other compliers – Mohamed Jun 10 '19 at 9:18
  • In this case it was easy because you only need to change the pragma and correct the compilation errors/warnings. But I recommend to revise all the code. – alberto Jun 10 '19 at 9:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.