@ -1 +1,2 @@ |
|||
wasm_exec.js |
|||
node_modules |
@ -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") |
@ -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 |
|||
|
|||
|
@ -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() |
@ -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=" |
|||
} |
|||
} |
|||
} |
@ -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" |
|||
} |
|||
} |