arnaucube
arnaucube/websnarkPublic Self-hosted repository
websnark/src/build_timesscalar.js
src/build_timesscalar.jsRaw
 1/*
 2    Copyright 2019 0KIMS association.
 3
 4    This file is part of websnark (Web Assembly zkSnark Prover).
 5
 6    websnark is a free software: you can redistribute it and/or modify it
 7    under the terms of the GNU General Public License as published by
 8    the Free Software Foundation, either version 3 of the License, or
 9    (at your option) any later version.
10
11    websnark is distributed in the hope that it will be useful, but WITHOUT
12    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13    or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14    License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with websnark. If not, see <https://www.gnu.org/licenses/>.
18*/
19
20module.exports = function buildTimesScalar(module, fnName, elementLen, opAB, opAA, fPrefix) {
21
22    const f = module.addFunction(fnName);
23    f.addParam("base", "i32");
24    f.addParam("scalar", "i32");
25    f.addParam("scalarLength", "i32");
26    f.addParam("r", "i32");
27    f.addLocal("i", "i32");
28    f.addLocal("b", "i32");
29
30    const c = f.getCodeBuilder();
31
32    const aux = c.i32_const(module.alloc(elementLen));
33
34    f.addCode(c.call(fPrefix + "_copy", c.getLocal("base"), aux));
35
36    f.addCode(c.call(fPrefix + "_zero", c.getLocal("r")));
37
38    f.addCode(c.setLocal("i", c.getLocal("scalarLength")));
39    f.addCode(c.block(c.loop(
40        c.setLocal("i", c.i32_sub(c.getLocal("i"), c.i32_const(1))),
41
42        c.setLocal(
43            "b",
44            c.i32_load8_u(
45                c.i32_add(
46                    c.getLocal("scalar"),
47                    c.getLocal("i")
48                )
49            )
50        ),
51        ...innerLoop(),
52        c.br_if(1, c.i32_eqz ( c.getLocal("i") )),
53        c.br(0)
54    )));
55
56
57    function innerLoop() {
58        const code = [];
59        for (let i=0; i<8; i++) {
60            code.push(
61                ...c.call(opAA, c.getLocal("r"), c.getLocal("r")),
62                ...c.if(
63                    c.i32_ge_u( c.getLocal("b"), c.i32_const(0x80 >> i)),
64                    [
65                        ...c.setLocal(
66                            "b",
67                            c.i32_sub(
68                                c.getLocal("b"),
69                                c.i32_const(0x80 >> i)
70                            )
71                        ),
72                        ...c.call(opAB, aux, c.getLocal("r"), c.getLocal("r"))
73                    ]
74                )
75            );
76        }
77        return code;
78    }
79
80};