UNPKG

wasmcurves

Version:

elliptic curves implementations in wasm

339 lines (313 loc) 11.1 kB
module.exports = function buildQAP(module, prefix, prefixField) { const n64 = module.modules[prefixField].n64; const n8 = n64*8; function buildBuildABC() { const f = module.addFunction(prefix+"_buildABC"); f.addParam("pCoefs", "i32"); f.addParam("nCoefs", "i32"); f.addParam("pWitness", "i32"); f.addParam("pA", "i32"); f.addParam("pB", "i32"); f.addParam("pC", "i32"); f.addParam("offsetOut", "i32"); f.addParam("nOut", "i32"); f.addParam("offsetWitness", "i32"); f.addParam("nWitness", "i32"); f.addLocal("it", "i32"); f.addLocal("ita", "i32"); f.addLocal("itb", "i32"); f.addLocal("last", "i32"); f.addLocal("m", "i32"); f.addLocal("c", "i32"); f.addLocal("s", "i32"); f.addLocal("pOut", "i32"); const c = f.getCodeBuilder(); const aux = c.i32_const(module.alloc(n8)); f.addCode( // Set output a and b to 0 c.setLocal("ita", c.getLocal("pA")), c.setLocal("itb", c.getLocal("pB")), c.setLocal( "last", c.i32_add( c.getLocal("pA"), c.i32_mul( c.getLocal("nOut"), c.i32_const(n8) ) ) ), c.block(c.loop( c.br_if( 1, c.i32_eq( c.getLocal("ita"), c.getLocal("last") ) ), c.call(prefixField + "_zero", c.getLocal("ita")), c.call(prefixField + "_zero", c.getLocal("itb")), c.setLocal("ita", c.i32_add(c.getLocal("ita"), c.i32_const(n8))), c.setLocal("itb", c.i32_add(c.getLocal("itb"), c.i32_const(n8))), c.br(0) )), c.setLocal("it", c.getLocal("pCoefs")), c.setLocal( "last", c.i32_add( c.getLocal("pCoefs"), c.i32_mul( c.getLocal("nCoefs"), c.i32_const(n8+12) ) ) ), c.block(c.loop( c.br_if( 1, c.i32_eq( c.getLocal("it"), c.getLocal("last") ) ), c.setLocal( "s", c.i32_load(c.getLocal("it"), 8) ), c.if( c.i32_or( c.i32_lt_u( c.getLocal("s"), c.getLocal("offsetWitness"), ), c.i32_ge_u( c.getLocal("s"), c.i32_add( c.getLocal("offsetWitness"), c.getLocal("nWitness"), ) ) ), [ ...c.setLocal("it", c.i32_add(c.getLocal("it"), c.i32_const(n8+12))), ...c.br(1) ] ), c.setLocal( "m", c.i32_load(c.getLocal("it")) ), c.if( c.i32_eq(c.getLocal("m"), c.i32_const(0)), c.setLocal("pOut", c.getLocal("pA")), c.if( c.i32_eq(c.getLocal("m"), c.i32_const(1)), c.setLocal("pOut", c.getLocal("pB")), [ ...c.setLocal("it", c.i32_add(c.getLocal("it"), c.i32_const(n8+12))), ...c.br(1) ] ) ), c.setLocal( "c", c.i32_load(c.getLocal("it"), 4) ), c.if( c.i32_or( c.i32_lt_u( c.getLocal("c"), c.getLocal("offsetOut"), ), c.i32_ge_u( c.getLocal("c"), c.i32_add( c.getLocal("offsetOut"), c.getLocal("nOut"), ) ) ), [ ...c.setLocal("it", c.i32_add(c.getLocal("it"), c.i32_const(n8+12))), ...c.br(1) ] ), c.setLocal( "pOut", c.i32_add( c.getLocal("pOut"), c.i32_mul( c.i32_sub( c.getLocal("c"), c.getLocal("offsetOut") ), c.i32_const(n8) ) ) ), c.call( prefixField + "_mul", c.i32_add( c.getLocal("pWitness"), c.i32_mul( c.i32_sub(c.getLocal("s"), c.getLocal("offsetWitness")), c.i32_const(n8) ) ), c.i32_add( c.getLocal("it"), c.i32_const(12)), aux ), c.call( prefixField + "_add", c.getLocal("pOut"), aux, c.getLocal("pOut"), ), c.setLocal("it", c.i32_add(c.getLocal("it"), c.i32_const(n8+12))), c.br(0) )), c.setLocal("ita", c.getLocal("pA")), c.setLocal("itb", c.getLocal("pB")), c.setLocal("it", c.getLocal("pC")), c.setLocal( "last", c.i32_add( c.getLocal("pA"), c.i32_mul( c.getLocal("nOut"), c.i32_const(n8) ) ) ), c.block(c.loop( c.br_if( 1, c.i32_eq( c.getLocal("ita"), c.getLocal("last") ) ), c.call( prefixField + "_mul", c.getLocal("ita"), c.getLocal("itb"), c.getLocal("it") ), c.setLocal("ita", c.i32_add(c.getLocal("ita"), c.i32_const(n8))), c.setLocal("itb", c.i32_add(c.getLocal("itb"), c.i32_const(n8))), c.setLocal("it", c.i32_add(c.getLocal("it"), c.i32_const(n8))), c.br(0) )), ); } function buildJoinABC() { const f = module.addFunction(prefix+"_joinABC"); f.addParam("pA", "i32"); f.addParam("pB", "i32"); f.addParam("pC", "i32"); f.addParam("n", "i32"); f.addParam("pP", "i32"); f.addLocal("ita", "i32"); f.addLocal("itb", "i32"); f.addLocal("itc", "i32"); f.addLocal("itp", "i32"); f.addLocal("last", "i32"); const c = f.getCodeBuilder(); const aux = c.i32_const(module.alloc(n8)); f.addCode( c.setLocal("ita", c.getLocal("pA")), c.setLocal("itb", c.getLocal("pB")), c.setLocal("itc", c.getLocal("pC")), c.setLocal("itp", c.getLocal("pP")), c.setLocal( "last", c.i32_add( c.getLocal("pA"), c.i32_mul( c.getLocal("n"), c.i32_const(n8) ) ) ), c.block(c.loop( c.br_if( 1, c.i32_eq( c.getLocal("ita"), c.getLocal("last") ) ), c.call( prefixField + "_mul", c.getLocal("ita"), c.getLocal("itb"), aux ), c.call( prefixField + "_sub", aux, c.getLocal("itc"), c.getLocal("itp"), ), c.setLocal("ita", c.i32_add(c.getLocal("ita"), c.i32_const(n8))), c.setLocal("itb", c.i32_add(c.getLocal("itb"), c.i32_const(n8))), c.setLocal("itc", c.i32_add(c.getLocal("itc"), c.i32_const(n8))), c.setLocal("itp", c.i32_add(c.getLocal("itp"), c.i32_const(n8))), c.br(0) )) ); } function buildBatchAdd() { const f = module.addFunction(prefix+"_batchAdd"); f.addParam("pa", "i32"); f.addParam("pb", "i32"); f.addParam("n", "i32"); f.addParam("pr", "i32"); f.addLocal("ita", "i32"); f.addLocal("itb", "i32"); f.addLocal("itr", "i32"); f.addLocal("last", "i32"); const c = f.getCodeBuilder(); f.addCode( c.setLocal("ita", c.getLocal("pa")), c.setLocal("itb", c.getLocal("pb")), c.setLocal("itr", c.getLocal("pr")), c.setLocal( "last", c.i32_add( c.getLocal("pa"), c.i32_mul( c.getLocal("n"), c.i32_const(n8) ) ) ), c.block(c.loop( c.br_if( 1, c.i32_eq( c.getLocal("ita"), c.getLocal("last") ) ), c.call( prefixField + "_add", c.getLocal("ita"), c.getLocal("itb"), c.getLocal("itr"), ), c.setLocal("ita", c.i32_add(c.getLocal("ita"), c.i32_const(n8))), c.setLocal("itb", c.i32_add(c.getLocal("itb"), c.i32_const(n8))), c.setLocal("itr", c.i32_add(c.getLocal("itr"), c.i32_const(n8))), c.br(0) )) ); } buildBuildABC(); buildJoinABC(); buildBatchAdd(); module.exportFunction(prefix + "_buildABC"); module.exportFunction(prefix + "_joinABC"); module.exportFunction(prefix + "_batchAdd"); return prefix; };