├── .gitignore ├── .travis.yml ├── truffle.js ├── truffle-config.js ├── migrations └── 1_initial_migration.js ├── README.md ├── contracts ├── Migrations.sol ├── WeightedMultiSig.sol ├── WMSTestProxy.sol ├── BGLS.sol └── BGLSTestProxy.sol ├── test ├── testBGLS.js └── testWeightedMultiSig.js └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | "node" 4 | before_script: 5 | - npm install -g truffle 6 | script: truffle test 7 | 8 | -------------------------------------------------------------------------------- /truffle.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | // See 3 | // to customize your Truffle configuration! 4 | }; 5 | -------------------------------------------------------------------------------- /truffle-config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | // See 3 | // to customize your Truffle configuration! 4 | }; 5 | -------------------------------------------------------------------------------- /migrations/1_initial_migration.js: -------------------------------------------------------------------------------- 1 | var Migrations = artifacts.require("./Migrations.sol"); 2 | 3 | module.exports = function(deployer) { 4 | deployer.deploy(Migrations); 5 | }; 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # bgls-on-evm 2 | Library for the verification of BGLS signatures on the EVM using Solidity. 3 | 4 | Designed to be cross compatible with [bgls](https://github.com/jlandrews/bgls) 5 | 6 | WIP 7 | -------------------------------------------------------------------------------- /contracts/Migrations.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.17; 2 | 3 | contract Migrations { 4 | address public owner; 5 | uint public last_completed_migration; 6 | 7 | modifier restricted() { 8 | if (msg.sender == owner) _; 9 | } 10 | 11 | function Migrations() public { 12 | owner = msg.sender; 13 | } 14 | 15 | function setCompleted(uint completed) public restricted { 16 | last_completed_migration = completed; 17 | } 18 | 19 | function upgrade(address new_address) public restricted { 20 | Migrations upgraded = Migrations(new_address); 21 | upgraded.setCompleted(last_completed_migration); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /test/testBGLS.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const BGLS = artifacts.require("BGLS"); 4 | const BGLSTestProxy = artifacts.require("BGLSTestProxy"); 5 | 6 | contract("BGLS", async (accounts) => { 7 | let bgls; 8 | let bglsTest; 9 | beforeEach(async () => { 10 | bgls = await BGLS.new(); 11 | bglsTest = await BGLSTestProxy.new(); 12 | }) 13 | it("should verify trivial pairing", async () => { 14 | assert(await bglsTest.pairingCheckTrivial.call()); 15 | }); 16 | it("should verify scalar multiple pairing", async () => { 17 | assert(await bglsTest.pairingCheckMult.call()); 18 | }); 19 | it("should add points correctly", async () => { 20 | assert(await bglsTest.addTest.call()); 21 | }) 22 | it("should do scalar multiplication correctly", async () => { 23 | assert(await bglsTest.scalarTest.call()); 24 | }) 25 | it("should verify a simple signature correctly", async () => { 26 | assert(await bglsTest.testSignature.call([12345,54321,10101,20202,30303])); 27 | }) 28 | it("should sum points correctly", async () => { 29 | assert(await bglsTest.testSumPoints.call()); 30 | }) 31 | }) 32 | -------------------------------------------------------------------------------- /contracts/WeightedMultiSig.sol: -------------------------------------------------------------------------------- 1 | 2 | pragma solidity ^0.4.17; 3 | 4 | import "contracts/BGLS.sol"; 5 | 6 | contract WeightedMultiSig is BGLS { 7 | G1[] pairKeys; 8 | uint[] weights; 9 | uint threshold; 10 | uint state; 11 | 12 | function WeightedMultiSig(uint _threshold, uint[] pairKeyX, uint[] pairKeyY, uint[] _weights) public { 13 | setStateInternal(0, _threshold, pairKeyX, pairKeyY, _weights); 14 | } 15 | 16 | function updateState(uint numSigners, uint[] newState, bytes signers, 17 | uint sigX, uint sigY, 18 | uint pkXi, uint pkXr, uint pkYi, uint pkYr) public returns (bool) { 19 | require(checkSig(signers, newState, sigX, sigY, pkXi, pkXr, pkYi, pkYr)); 20 | require(newState.length == 3*numSigners + 2); 21 | require(newState[0] > state); 22 | uint[] memory pairKeyX = new uint[](numSigners); 23 | uint[] memory pairKeyY = new uint[](numSigners); 24 | uint[] memory _weights = new uint[](numSigners); 25 | for (uint i = 0; i < numSigners; i++) { 26 | pairKeyX[i] = newState[i*3+2]; 27 | pairKeyY[i] = newState[i*3+3]; 28 | _weights[i] = newState[i*3+4]; 29 | } 30 | setStateInternal(newState[0], newState[1], pairKeyX, pairKeyY, _weights); 31 | return true; 32 | } 33 | 34 | function setStateInternal(uint _state, uint _threshold, uint[] pairKeyX, uint[] pairKeyY, uint[] _weights) internal { 35 | assert(pairKeyX.length == pairKeyY.length && pairKeyX.length == _weights.length); 36 | pairKeys.length = pairKeyX.length; 37 | for (uint i = 0; i < pairKeyX.length; i++) { 38 | pairKeys[i] = G1(pairKeyX[i], pairKeyY[i]); 39 | } 40 | weights = _weights; 41 | threshold = _threshold; 42 | state = _state; 43 | } 44 | 45 | function isQuorum(bytes signers) public view returns (bool){ 46 | uint weight = 0; 47 | for (uint i = 0; i < weights.length; i++) { 48 | if (chkBit(signers,i)) { 49 | weight += weights[i]; 50 | } 51 | } 52 | return weight >= threshold; 53 | } 54 | 55 | function checkAggKey(bytes signers, G2 aggKey) internal returns (bool) { 56 | return pairingCheck(sumPoints(pairKeys, signers),g2,g1,aggKey); 57 | } 58 | 59 | function checkSig(bytes signers, uint[] message, 60 | uint sigX, uint sigY, 61 | uint pkXi, uint pkXr, uint pkYi, uint pkYr) public returns (bool) { 62 | G2 memory aggKey = G2(pkXi, pkXr, pkYi, pkYr); 63 | G1 memory sig = G1(sigX, sigY); 64 | return isQuorum(signers) && 65 | checkAggKey(signers, aggKey) && 66 | checkSignature(message, sig, aggKey); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /contracts/WMSTestProxy.sol: -------------------------------------------------------------------------------- 1 | 2 | pragma solidity ^0.4.17; 3 | 4 | import "contracts/WeightedMultiSig.sol"; 5 | 6 | contract WMSTestProxy is WeightedMultiSig { 7 | 8 | function WMSTestProxy(uint threshold, uint[] pkX, uint[] pkY, uint[] weights) public WeightedMultiSig(threshold, pkX, pkY, weights) { 9 | 10 | } 11 | 12 | function testPairKey1() public returns (bool) { 13 | G2 memory AggKey = G2( 14 | 12703405598006979409108671416960902338538868397248453921759384556929622558257, 15 | 142094823562702583669092464225103219873886198373818886253774429994499461119, 16 | 21792722069934396490667258760160363541978805696356802531479377933366930348185, 17 | 10504771741599673449168779439288281645955231116910341346670256599842843491846 18 | ); 19 | bytes memory bits = hex"01"; 20 | return checkAggKey(bits, AggKey); 21 | } 22 | 23 | function testPairKey2() public returns (bool) { 24 | G2 memory AggKey = G2( 25 | 20006812794463773049283962047975497795722587578259288681701348081786051400258, 26 | 1640508198157624193356029863862725978297346751018633260429156510910915938857, 27 | 19657010764300646747514652936900086863154235949329254169398625342920745373498, 28 | 9751811989559422309862820503052805635622815890436048409544629439386101906108 29 | ); 30 | bytes memory bits = hex"02"; 31 | return checkAggKey(bits, AggKey); 32 | } 33 | 34 | function testPairKey3() public returns (bool) { 35 | G2 memory AggKey = G2( 36 | 3345200110093539336711190345646581220821935982483784880520691485717959162160, 37 | 7346924326712924839060989642072626629212433038426584057787676375534652692102, 38 | 3900793141294734731207085523026699981765543221986463887497799365455723407478, 39 | 17921492704942051952697919983467136374983228635828398798891192294557048884178 40 | ); 41 | bytes memory bits = hex"04"; 42 | return checkAggKey(bits, AggKey); 43 | } 44 | 45 | function testPairKey4() public returns (bool) { 46 | G2 memory AggKey = G2( 47 | 21389565708435198914603722878218839479380959862620092247900549933119351524255, 48 | 1188244178233812896807769005779279536261682145821733162891182925241423144364, 49 | 7413139998987028316541871182188785623520863143046778007833426242136654511588, 50 | 11636786006650028318960036786271861610977319170482606727882205182092192278902 51 | ); 52 | bytes memory bits = hex"08"; 53 | return checkAggKey(bits, AggKey); 54 | } 55 | 56 | function testPairKey5() public returns (bool) { 57 | G2 memory AggKey = G2( 58 | 19937543458732154565154076188277050493702771691356212122830197297585839172817, 59 | 1065283751440878030458058090898905485318412299045221475718238281237832381108, 60 | 15747707797933322344134861606644256454202498251498043888932613691897963621833, 61 | 10197200283701669569763976293743546257101447758446954765388293798186868596696 62 | ); 63 | bytes memory bits = hex"10"; 64 | return checkAggKey(bits, AggKey); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /contracts/BGLS.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.17; 2 | 3 | contract BGLS { 4 | struct G1 { 5 | uint x; 6 | uint y; 7 | } 8 | G1 g1 = G1(1,2); 9 | 10 | struct G2 { 11 | uint xi; 12 | uint xr; 13 | uint yi; 14 | uint yr; 15 | } 16 | G2 g2 = G2( 17 | 11559732032986387107991004021392285783925812861821192530917403151452391805634, 18 | 10857046999023057135944570762232829481370756359578518086990519993285655852781, 19 | 4082367875863433681332203403145435568316851327593401208105741076214120093531, 20 | 8495653923123431417604973247489272438418190587263600148770280649306958101930 21 | ); 22 | 23 | function modPow(uint256 base, uint256 exponent, uint256 modulus) internal returns (uint256) { 24 | uint256[6] memory input = [32,32,32,base,exponent,modulus]; 25 | uint256[1] memory result; 26 | assembly { 27 | if iszero(call(not(0), 0x05, 0, input, 0xc0, result, 0x20)) { 28 | revert(0, 0) 29 | } 30 | } 31 | return result[0]; 32 | } 33 | 34 | function addPoints(G1 a, G1 b) internal returns (G1) { 35 | uint256[4] memory input = [a.x, a.y, b.x, b.y]; 36 | uint[2] memory result; 37 | assembly { 38 | if iszero(call(not(0), 0x06, 0, input, 0x80, result, 0x40)) { 39 | revert(0, 0) 40 | } 41 | } 42 | return G1(result[0], result[1]); 43 | } 44 | 45 | function chkBit(bytes b, uint x) public pure returns (bool) { 46 | return uint(b[x/8])&(uint(1)<<(x%8)) != 0; 47 | } 48 | 49 | function sumPoints(G1[] points, bytes indices) internal returns (G1) { 50 | G1 memory acc = G1(0,0); 51 | for (uint i = 0; i < points.length; i++) { 52 | if (chkBit(indices, i)) { 53 | acc = addPoints(acc, points[i]); 54 | } 55 | } 56 | return G1(acc.x, acc.y); 57 | } 58 | 59 | function scalarMultiply(G1 point, uint256 scalar) internal returns(G1) { 60 | uint256[3] memory input = [point.x, point.y, scalar]; 61 | uint[2] memory result; 62 | assembly { 63 | if iszero(call(not(0), 0x07, 0, input, 0x60, result, 0x40)) { 64 | revert(0, 0) 65 | } 66 | } 67 | return G1(result[0], result[1]); 68 | } 69 | 70 | function pairingCheck(G1 a, G2 x, G1 b, G2 y) internal returns (bool) { 71 | //returns e(a,x) == e(b,y) 72 | uint256[12] memory input = [ 73 | a.x, a.y, x.xi, x.xr, x.yi, x.yr, b.x, prime - b.y, y.xi, y.xr, y.yi, y.yr 74 | ]; 75 | uint[1] memory result; 76 | assembly { 77 | if iszero(call(not(0), 0x08, 0, input, 0x180, result, 0x20)) { 78 | revert(0, 0) 79 | } 80 | } 81 | return result[0]==1; 82 | } 83 | 84 | 85 | uint256 prime = 21888242871839275222246405745257275088696311157297823662689037894645226208583; 86 | uint256 pminus = 21888242871839275222246405745257275088696311157297823662689037894645226208582; 87 | uint256 pplus = 21888242871839275222246405745257275088696311157297823662689037894645226208584; 88 | 89 | function hashToG1(uint[] b) internal returns (G1) { 90 | uint x = 0; 91 | while (true) { 92 | uint256 hx = uint256(keccak256(b,byte(x)))%prime; 93 | uint256 px = (modPow(hx,3,prime) + 3); 94 | if (modPow(px, pminus/2, prime) == 1) { 95 | uint256 py = modPow(px, pplus/4, prime); 96 | if (uint(keccak256(b,byte(255)))%2 == 0) 97 | return G1(hx,py); 98 | else 99 | return G1(hx,prime-py); 100 | } else { 101 | x++; 102 | } 103 | } 104 | } 105 | 106 | function checkSignature(uint[] message, G1 sig, G2 aggKey) internal returns (bool) { 107 | return pairingCheck(sig, g2, hashToG1(message), aggKey); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /contracts/BGLSTestProxy.sol: -------------------------------------------------------------------------------- 1 | 2 | pragma solidity ^0.4.17; 3 | 4 | import "contracts/BGLS.sol"; 5 | 6 | contract BGLSTestProxy is BGLS { 7 | function pairingCheckTrivial() public returns (bool) { 8 | return pairingCheck(g1,g2,g1,g2); 9 | } 10 | function pairingCheckMult() public returns (bool) { 11 | return pairingCheck(scalarMultiply(g1,12345),g2,scalarMultiply(g1,12345),g2); 12 | } 13 | event PrintG1(string t, uint x, uint y); 14 | 15 | function addTest() public returns (bool) { 16 | G1 memory a = G1( 17 | 9121282642809701931333593728297233225556711250127745709186816755779879923737, 18 | 8783642022119951289582979607207867126556038468480503109520224385365741455513); 19 | G1 memory b = G1( 20 | 19430493116922072356830709910231609246608721301711710668649991649389881488730, 21 | 4110959498627045907440291871300490703579626657177845575364169615082683328588); 22 | G1 memory ab = addPoints(a,b); 23 | G1 memory expected = G1( 24 | 17981918273786386398769813244173616322667195802888989780909050086192926768907, 25 | 18658404630663819378315425423756597890713010608083111245835977740656931644247); 26 | return ab.x == expected.x && ab.y == expected.y; 27 | } 28 | function scalarTest() public returns (bool) { 29 | G1 memory expected = G1( 30 | 11404940445424363337823423808411232433223590477377068719858726746225925918890, 31 | 2424505913866680143139332783087422983475325405994502385033744924144562639386 32 | ); 33 | G1 memory res = scalarMultiply(g1,12345); 34 | return res.x == expected.x && res.y == expected.y; 35 | } 36 | function hashToG1Test() public returns (bool) { 37 | return false; 38 | } 39 | 40 | function testSumPoints() public returns (bool) { 41 | G1[] memory points = new G1[](5); 42 | points[0] = G1( 43 | 9121282642809701931333593728297233225556711250127745709186816755779879923737, 44 | 8783642022119951289582979607207867126556038468480503109520224385365741455513 45 | ); 46 | points[1] = G1( 47 | 19430493116922072356830709910231609246608721301711710668649991649389881488730, 48 | 4110959498627045907440291871300490703579626657177845575364169615082683328588 49 | ); 50 | points[2] = G1( 51 | 20422461965303760684972432833393275482011872214285431434762613176151735978626, 52 | 4340414105609005319657729201597518376025644764079088797074616044782247204946 53 | ); 54 | points[3] = G1( 55 | 298572075162454679163670333497954782367165699328351139754869100063308445382, 56 | 19406526149564276287084583577153409216667341395977223898932369699699605058292 57 | ); 58 | points[4] = G1( 59 | 13617110937608119725159715497522173305174557569388165671955816638318382445127, 60 | 5989220236822003292279415228814579004737160217409816506111930966995235750604 61 | ); 62 | //G1 memory p1 = sumPoints(points, hex"01"); 63 | //G1 memory p2 = sumPoints(points, hex"02"); 64 | //G1 memory p3 = sumPoints(points, hex"04"); 65 | //G1 memory p4 = sumPoints(points, hex"08"); 66 | //G1 memory p5 = sumPoints(points, hex"10"); 67 | //G1 memory p12 = sumPoints(points, hex"03"); 68 | //G1 memory p13 = sumPoints(points, hex"05"); 69 | //G1 memory p23 = sumPoints(points, hex"06"); 70 | G1 memory sumall = sumPoints(points, hex"0f"); 71 | //G1 memory add12 = addPoints(points[0], points[1]); 72 | //G1 memory add13 = addPoints(points[0], points[2]); 73 | //G1 memory add23 = addPoints(points[1], points[2]); 74 | G1 memory addall = addPoints(points[0], addPoints(points[1], addPoints(points[2], points[3]))); 75 | //PrintG1("p1",p1.x, p1.y); 76 | //PrintG1("points[0]", points[0].x, points[0].y); 77 | //PrintG1("p2",p2.x, p2.y); 78 | //PrintG1("points[1]", points[1].x, points[1].y); 79 | //PrintG1("p3",p3.x, p3.y); 80 | //PrintG1("points[2]", points[2].x, points[2].y); 81 | //PrintG1("p4",p4.x, p4.y); 82 | //PrintG1("points[3]", points[3].x, points[3].y); 83 | //PrintG1("p5",p5.x, p5.y); 84 | //PrintG1("points[4]", points[4].x, points[4].y); 85 | //PrintG1("p12",p12.x, p12.y); 86 | //PrintG1("add12", add12.x, add12.y); 87 | //PrintG1("p13",p13.x, p13.y); 88 | //PrintG1("add13", add13.x, add13.y); 89 | //PrintG1("p23",p23.x, p23.y); 90 | //PrintG1("add23", add23.x, add23.y); 91 | PrintG1("sumall", sumall.x, sumall.y); 92 | PrintG1("addall", addall.x, addall.y); 93 | return sumall.x == addall.x && sumall.y == addall.y; 94 | //points[0].x == p1.x && points[0].y == p1.y && 95 | //points[1].x == p2.x && points[1].y == p2.y && 96 | //points[2].x == p3.x && points[2].y == p3.y && 97 | //points[3].x == p4.x && points[3].y == p4.y && 98 | //points[4].x == p5.x && points[4].y == p5.y && 99 | //p12.x == add12.x && p12.y == add12.y && 100 | //p13.x == add13.x && p13.y == add13.y && 101 | //p23.x == add23.x && p23.y == add23.y && 102 | } 103 | 104 | 105 | 106 | function testSignature(uint[] values) public returns (bool) { 107 | uint privKey = 123456789; 108 | G2 memory pubKey = G2( 109 | 12703405598006979409108671416960902338538868397248453921759384556929622558257, 110 | 142094823562702583669092464225103219873886198373818886253774429994499461119, 111 | 21792722069934396490667258760160363541978805696356802531479377933366930348185, 112 | 10504771741599673449168779439288281645955231116910341346670256599842843491846 113 | ); 114 | G1 memory h = hashToG1(values); 115 | G1 memory sig = scalarMultiply(h,privKey); 116 | return pairingCheck(sig, g2, h, pubKey); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /test/testWeightedMultiSig.js: -------------------------------------------------------------------------------- 1 | 2 | const WeightedMultiSig = artifacts.require("WeightedMultiSig"); 3 | const WMSTestProxy = artifacts.require("WMSTestProxy"); 4 | 5 | contract("WeightedMultiSig", async (accounts) => { 6 | let WMS; 7 | let WMSt; 8 | function promiseToThrow(p, msg) { 9 | return p.then(_ => false).catch(_ => true).then(res => 10 | assert(res, msg)); 11 | } 12 | beforeEach(async () => { 13 | WMS = await WeightedMultiSig.new(67,[ 14 | "9121282642809701931333593728297233225556711250127745709186816755779879923737", 15 | "19430493116922072356830709910231609246608721301711710668649991649389881488730", 16 | "20422461965303760684972432833393275482011872214285431434762613176151735978626", 17 | "298572075162454679163670333497954782367165699328351139754869100063308445382", 18 | "13617110937608119725159715497522173305174557569388165671955816638318382445127" 19 | ],[ 20 | "8783642022119951289582979607207867126556038468480503109520224385365741455513", 21 | "4110959498627045907440291871300490703579626657177845575364169615082683328588", 22 | "4340414105609005319657729201597518376025644764079088797074616044782247204946", 23 | "19406526149564276287084583577153409216667341395977223898932369699699605058292", 24 | "5989220236822003292279415228814579004737160217409816506111930966995235750604" 25 | ],[20,20,20,20,20]); 26 | WMSt = await WMSTestProxy.new(67,[ 27 | "9121282642809701931333593728297233225556711250127745709186816755779879923737", 28 | "19430493116922072356830709910231609246608721301711710668649991649389881488730", 29 | "20422461965303760684972432833393275482011872214285431434762613176151735978626", 30 | "298572075162454679163670333497954782367165699328351139754869100063308445382", 31 | "13617110937608119725159715497522173305174557569388165671955816638318382445127" 32 | ],[ 33 | "8783642022119951289582979607207867126556038468480503109520224385365741455513", 34 | "4110959498627045907440291871300490703579626657177845575364169615082683328588", 35 | "4340414105609005319657729201597518376025644764079088797074616044782247204946", 36 | "19406526149564276287084583577153409216667341395977223898932369699699605058292", 37 | "5989220236822003292279415228814579004737160217409816506111930966995235750604" 38 | ],[20,20,20,20,20]); 39 | }) 40 | it("should verify maximum quorum correctly", async () => { 41 | let res = await WMS.isQuorum.call("0xff"); 42 | assert.equal(res,true); 43 | }); 44 | it("should block null quorum", async () => { 45 | let res = await WMS.isQuorum.call("0x00"); 46 | assert.equal(res,false); 47 | }) 48 | it("should pass with 4 of 5", async () => { 49 | assert.equal(await WMS.isQuorum.call("0x1e"), true); 50 | assert.equal(await WMS.isQuorum.call("0x1d"), true); 51 | assert.equal(await WMS.isQuorum.call("0x1b"), true); 52 | assert.equal(await WMS.isQuorum.call("0x17"), true); 53 | assert.equal(await WMS.isQuorum.call("0x0f"), true); 54 | }) 55 | it("should fail with 3 of 5", async () => { 56 | assert.equal(await WMS.isQuorum.call("0x07"), false); 57 | assert.equal(await WMS.isQuorum.call("0x0b"), false); 58 | assert.equal(await WMS.isQuorum.call("0x0d"), false); 59 | assert.equal(await WMS.isQuorum.call("0x0e"), false); 60 | assert.equal(await WMS.isQuorum.call("0x13"), false); 61 | assert.equal(await WMS.isQuorum.call("0x15"), false); 62 | assert.equal(await WMS.isQuorum.call("0x16"), false); 63 | assert.equal(await WMS.isQuorum.call("0x19"), false); 64 | assert.equal(await WMS.isQuorum.call("0x1a"), false); 65 | assert.equal(await WMS.isQuorum.call("0x1c"), false); 66 | }) 67 | it("should check aggregate keys against pair keys correctly (1)", async () => { 68 | assert(await WMSt.testPairKey1.call()); 69 | }) 70 | it("should check aggregate keys against pair keys correctly (2)", async () => { 71 | assert(await WMSt.testPairKey2.call()); 72 | }) 73 | it("should check aggregate keys against pair keys correctly (3)", async () => { 74 | assert(await WMSt.testPairKey3.call()); 75 | }) 76 | it("should check aggregate keys against pair keys correctly (4)", async () => { 77 | assert(await WMSt.testPairKey4.call()); 78 | }) 79 | it("should check aggregate keys against pair keys correctly (5)", async () => { 80 | assert(await WMSt.testPairKey5.call()); 81 | }) 82 | 83 | it("should be able to update with 4/5 of equal weight", async () => { 84 | assert(await WMS.updateState.call(1, [1, 67, 85 | "9121282642809701931333593728297233225556711250127745709186816755779879923737", 86 | "8783642022119951289582979607207867126556038468480503109520224385365741455513", 87 | 100 88 | ], "0x0f", 89 | "2948269716085502948790009686650452414675481763019106577396688261393573590418", //sigX 90 | "4670268754090224810492676966567128460691441819810059675575673092251639253273", //sigy 91 | "2716981870054376425540623498944271869143173296821421331478826053599476430854", //pkxi 92 | "4207954545713722779397243242064268224396102704576018253000218082904392461892", //pkxr 93 | "15016217483528080919615640796038236162852104966225325968042839587187338783249", //pkyi 94 | "14823056799673950316800545417245630398819170129662340134056907505652527393991")); //pkyr 95 | }) 96 | it("should fail with modified sig", async () => { 97 | promiseToThrow(WMS.updateState.call(1, [1, 67, 98 | "9121282642809701931333593728297233225556711250127745709186816755779879923737", 99 | "8783642022119951289582979607207867126556038468480503109520224385365741455513", 100 | 100 101 | ], "0x0f", 102 | "2948269716085502948790009686650452414675481763019106577396688261393573590417", //sigX 103 | "4670268754090224810492676966567128460691441819810059675575673092251639253273", //sigy 104 | "2716981870054376425540623498944271869143173296821421331478826053599476430854", //pkxi 105 | "4207954545713722779397243242064268224396102704576018253000218082904392461892", //pkxr 106 | "15016217483528080919615640796038236162852104966225325968042839587187338783249", //pkyi 107 | "14823056799673950316800545417245630398819170129662340134056907505652527393991"), //pkyr 108 | "modified sig"); 109 | }) 110 | it("should fail with modified pubkey", async () => { 111 | promiseToThrow(WMS.updateState.call(1, [1, 67, 112 | "9121282642809701931333593728297233225556711250127745709186816755779879923737", 113 | "8783642022119951289582979607207867126556038468480503109520224385365741455513", 114 | 100 115 | ], "0x0f", 116 | "2948269716085502948790009686650452414675481763019106577396688261393573590418", //sigX 117 | "4670268754090224810492676966567128460691441819810059675575673092251639253273", //sigy 118 | "2716981870054376425540623498944271869143173296821421331478826053599476430854", //pkxi 119 | "4207954545713722779397243242064268224396102704576018253000218082904392461892", //pkxr 120 | "15016217483528080919615640796038236162852104966225325968042839587187338783249", //pkyi 121 | "14823056799673950316800545417245630398819170129662340134056907505652527393990"), //pkyr 122 | "modified pubkey"); 123 | }) 124 | 125 | 126 | }) 127 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | --------------------------------------------------------------------------------