UNPKG

@kotevode/ffjavascript

Version:

Finite Field Library in Javascript

131 lines (102 loc) 4.05 kB
export default function buildPairing(curve) { const tm = curve.tm; curve.pairing = function pairing(a, b) { tm.startSyncOp(); const pA = tm.allocBuff(curve.G1.toJacobian(a)); const pB = tm.allocBuff(curve.G2.toJacobian(b)); const pRes = tm.alloc(curve.Gt.n8); tm.instance.exports[curve.name + "_pairing"](pA, pB, pRes); const res = tm.getBuff(pRes, curve.Gt.n8); tm.endSyncOp(); return res; }; curve.pairingEq = async function pairingEq() { let buffCt; let nEqs; if ((arguments.length % 2) == 1) { buffCt = arguments[arguments.length-1]; nEqs = (arguments.length -1) /2; } else { buffCt = curve.Gt.one; nEqs = arguments.length /2; } const opPromises = []; for (let i=0; i<nEqs; i++) { const task = []; const g1Buff = curve.G1.toJacobian(arguments[i*2]); task.push({cmd: "ALLOCSET", var: 0, buff: g1Buff}); task.push({cmd: "ALLOC", var: 1, len: curve.prePSize}); const g2Buff = curve.G2.toJacobian(arguments[i*2 +1]); task.push({cmd: "ALLOCSET", var: 2, buff: g2Buff}); task.push({cmd: "ALLOC", var: 3, len: curve.preQSize}); task.push({cmd: "ALLOC", var: 4, len: curve.Gt.n8}); task.push({cmd: "CALL", fnName: curve.name + "_prepareG1", params: [ {var: 0}, {var: 1} ]}); task.push({cmd: "CALL", fnName: curve.name + "_prepareG2", params: [ {var: 2}, {var: 3} ]}); task.push({cmd: "CALL", fnName: curve.name + "_millerLoop", params: [ {var: 1}, {var: 3}, {var: 4} ]}); task.push({cmd: "GET", out: 0, var: 4, len: curve.Gt.n8}); opPromises.push( tm.queueAction(task) ); } const result = await Promise.all(opPromises); tm.startSyncOp(); const pRes = tm.alloc(curve.Gt.n8); tm.instance.exports.ftm_one(pRes); for (let i=0; i<result.length; i++) { const pMR = tm.allocBuff(result[i][0]); tm.instance.exports.ftm_mul(pRes, pMR, pRes); } tm.instance.exports[curve.name + "_finalExponentiation"](pRes, pRes); const pCt = tm.allocBuff(buffCt); const r = !!tm.instance.exports.ftm_eq(pRes, pCt); tm.endSyncOp(); return r; }; curve.prepareG1 = function(p) { this.tm.startSyncOp(); const pP = this.tm.allocBuff(p); const pPrepP = this.tm.alloc(this.prePSize); this.tm.instance.exports[this.name + "_prepareG1"](pP, pPrepP); const res = this.tm.getBuff(pPrepP, this.prePSize); this.tm.endSyncOp(); return res; }; curve.prepareG2 = function(q) { this.tm.startSyncOp(); const pQ = this.tm.allocBuff(q); const pPrepQ = this.tm.alloc(this.preQSize); this.tm.instance.exports[this.name + "_prepareG2"](pQ, pPrepQ); const res = this.tm.getBuff(pPrepQ, this.preQSize); this.tm.endSyncOp(); return res; }; curve.millerLoop = function(preP, preQ) { this.tm.startSyncOp(); const pPreP = this.tm.allocBuff(preP); const pPreQ = this.tm.allocBuff(preQ); const pRes = this.tm.alloc(this.Gt.n8); this.tm.instance.exports[this.name + "_millerLoop"](pPreP, pPreQ, pRes); const res = this.tm.getBuff(pRes, this.Gt.n8); this.tm.endSyncOp(); return res; }; curve.finalExponentiation = function(a) { this.tm.startSyncOp(); const pA = this.tm.allocBuff(a); const pRes = this.tm.alloc(this.Gt.n8); this.tm.instance.exports[this.name + "_finalExponentiation"](pA, pRes); const res = this.tm.getBuff(pRes, this.Gt.n8); this.tm.endSyncOp(); return res; }; }