diff --git a/.gitignore b/.gitignore index 14fe915..dfd342d 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ wasm_exec.js +node_modules diff --git a/README.md b/README.md index fc4dd3c..5f488df 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,24 @@ # blindsig-client-server-example -Example of usage of https://github.com/arnaucube/go-blindsecp256k1, including a server representing the 'signer', and a web representing the 'user'. +Example of usage of [go-blindsecp256k1](https://github.com/arnaucube/go-blindsecp256k1) & [blindsecp256k1-js](https://github.com/arnaucube/blindsecp256k1-js), including a server representing the 'signer', and a web representing the 'user'. ## Run - Needs [go](https://golang.org/) installed -- Add the file `wasm_exec.js` in the `client` directory: -``` -cd client -cp "$(go env GOROOT)/misc/wasm/wasm_exec.js" . -``` +- If wants to use the WASM web version: + - Add the file `wasm_exec.js` in the `client` directory: + ``` + cd client + cp "$(go env GOROOT)/misc/wasm/wasm_exec.js" . + ``` - Run the server: ``` go run main.go ``` - Open the browser at `127.0.0.1:3000/web` + - `/web/index.html` shows the js version + - `/web/index-wasm.html` shows the WASM version + +## Loop test +Check [loop-test](https://github.com/arnaucube/blindsig-client-server-example/blob/master/client/loop-test/README.md) for more details. ## Flow ![diagram](https://raw.githubusercontent.com/arnaucube/blindsig-client-server-example/master/diagram.png "diagram") diff --git a/client/loop-test/README.md b/client/loop-test/README.md new file mode 100644 index 0000000..ab2ea53 --- /dev/null +++ b/client/loop-test/README.md @@ -0,0 +1,8 @@ +# Loop test +- Run the server from the repo root directory: `go run main.go` +- Install npm dependancies `npm install` +- Run the nodejs loop script: `node loop-test.js` + - This will print on the screen the number of iterations each 100 iterations + - And if there is an error verifying a signature, will print all the involved parameters + + diff --git a/client/loop-test/loop-test.js b/client/loop-test/loop-test.js new file mode 100644 index 0000000..1ba4d1c --- /dev/null +++ b/client/loop-test/loop-test.js @@ -0,0 +1,87 @@ +// This version uses https://github.com/arnaucube/blindsecp256k1-js + +const blindsecp256k1 = require('blindsecp256k1'); +const axios = require('axios'); + +let signerR, signerQ, m, mBlinded, userSecretData, blindedSig, sig, errCount, verified; + +const apiUrl = "http://127.0.0.1:3000"; + +function printPoint(name, p) { + console.log(`${name}:\n x: ${p.affineX.toString()}\n y: ${p.affineY.toString()}`); +} + +async function newRequest() { + try { + const res = await axios.get(apiUrl+'/request'); + signerR = blindsecp256k1.Point.fromAffine(blindsecp256k1.ecparams, + blindsecp256k1.newBigFromString(res.data.signerR.x), + blindsecp256k1.newBigFromString(res.data.signerR.y)); + signerQ = blindsecp256k1.Point.fromAffine(blindsecp256k1.ecparams, + blindsecp256k1.newBigFromString(res.data.signerQ.x), + blindsecp256k1.newBigFromString(res.data.signerQ.y)); + + let blindRes = blindsecp256k1.blind(m, signerR); + mBlinded = blindRes.mBlinded; + userSecretData = blindRes.userSecretData; + } catch (error) { + console.error(error); + } +} + +async function askBlindSign() { + try { + let data = { + m: mBlinded.toString(), + r: { + x: signerR.affineX.toString(), + y: signerR.affineY.toString() + } + }; + let res = await axios.post(apiUrl+'/blindsign', data); + blindedSig = blindsecp256k1.newBigFromString(res.data.sBlind); + sig = blindsecp256k1.unblind( + blindedSig, + userSecretData); + } catch (error) { + console.error(error); + } +} + +async function verify() { + verified = blindsecp256k1.verify(m, sig, signerQ); + if (!verified) { + errCount++; + printPoint("signerR", signerR); + printPoint("signerQ", signerQ); + console.log("m:", m); + console.log("mBlinded:", mBlinded.toString()); + console.log(`userSecretData:\n a: ${userSecretData.a.toString()}\n b: ${userSecretData.b.toString()}`); + printPoint("userSecretData.f", userSecretData.f); + console.log("blinded sig:", blindedSig.toString()); + console.log("sig.s:", sig.s.toString()); + printPoint("sig.f", sig.f); + console.log("verify", verified); + } +} + +async function iteration() { + await newRequest() + await askBlindSign() + await verify() +} + +async function main() { + errCount = 0; + for (let i=0; i<10000; i++) { + m = blindsecp256k1.newKeyPair().sk; + + await iteration() + if (i%100 ==0) { + console.log("number of iterations", i); + } + } + console.log("errCount", errCount); +} + +main() diff --git a/client/loop-test/package-lock.json b/client/loop-test/package-lock.json new file mode 100644 index 0000000..6223d24 --- /dev/null +++ b/client/loop-test/package-lock.json @@ -0,0 +1,77 @@ +{ + "name": "loop-test", + "version": "0.0.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@ethersproject/bytes": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.0.10.tgz", + "integrity": "sha512-vpu0v1LZ1j1s9kERQIMnVU69MyHEzUff7nqK9XuCU4vx+AM8n9lU2gj7jtJIvGSt9HzatK/6I6bWusI5nyuaTA==", + "requires": { + "@ethersproject/logger": "^5.0.8" + } + }, + "@ethersproject/keccak256": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.0.7.tgz", + "integrity": "sha512-zpUBmofWvx9PGfc7IICobgFQSgNmTOGTGLUxSYqZzY/T+b4y/2o5eqf/GGmD7qnTGzKQ42YlLNo+LeDP2qe55g==", + "requires": { + "@ethersproject/bytes": "^5.0.9", + "js-sha3": "0.5.7" + } + }, + "@ethersproject/logger": { + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.0.9.tgz", + "integrity": "sha512-kV3Uamv3XOH99Xf3kpIG3ZkS7mBNYcLDM00JSDtNgNB4BihuyxpQzIZPRIDmRi+95Z/R1Bb0X2kUNHa/kJoVrw==" + }, + "axios": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", + "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", + "requires": { + "follow-redirects": "^1.10.0" + } + }, + "bigi": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/bigi/-/bigi-1.4.2.tgz", + "integrity": "sha1-nGZalfiLiwj8Bc/XMfVhhZ1yWCU=" + }, + "bignumber.js": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-7.0.2.tgz", + "integrity": "sha512-TosM7Yg1Ux0ZCNwwS/tW95r3q9xIZstgsUGKWaez0Cgq8Oy3qia9RGvyG/fbxlQAvigjza1d057QNQLGvYXCeg==" + }, + "blindsecp256k1": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/blindsecp256k1/-/blindsecp256k1-0.0.5.tgz", + "integrity": "sha512-P+ahL3AlZY2RvtEUH7W3yidTNfDsu7yUsb2OOorEzsSE0cBovQKyBi+d883CVwbgjcW4mFFmHYgBZ0q+QOz9zQ==", + "requires": { + "@ethersproject/keccak256": "5.0.7", + "bigi": "^1.4.2", + "bignumber.js": "7.0.2", + "ecurve": "1.0.0" + } + }, + "ecurve": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ecurve/-/ecurve-1.0.0.tgz", + "integrity": "sha1-Ms/Vzl9CHpNRIGoz1OPP0280ZaQ=", + "requires": { + "bigi": "^1.1.0" + } + }, + "follow-redirects": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.2.tgz", + "integrity": "sha512-6mPTgLxYm3r6Bkkg0vNM0HTjfGrOEtsfbhagQvbxDEsEkpNhw582upBaoRZylzen6krEmxXJgt9Ju6HiI4O7BA==" + }, + "js-sha3": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", + "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=" + } + } +} diff --git a/client/loop-test/package.json b/client/loop-test/package.json new file mode 100644 index 0000000..30fda1d --- /dev/null +++ b/client/loop-test/package.json @@ -0,0 +1,15 @@ +{ + "name": "loop-test", + "version": "0.0.1", + "description": "", + "main": "loop-test.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "arnaucube", + "license": "ISC", + "dependencies": { + "axios": "^0.21.1", + "blindsecp256k1": "0.0.5" + } +}