circom/c/buildasm/buildzqfield.js
c/buildasm/buildzqfield.jsRaw
1const bigInt=require("big-integer");
2const path = require("path");
3const util = require("util");
4const renderFile = util.promisify(require("ejs").renderFile);
5
6const runningAsScript = !module.parent;
7
8
9class ZqBuilder {
10 constructor(q, name) {
11 const self = this;
12 this.q=bigInt(q);
13 this.n64 = Math.floor((this.q.bitLength() - 1) / 64)+1;
14 this.name = name;
15 this.bigInt = bigInt;
16 this.lastTmp=0;
17 this.global = {};
18 this.global.tmpLabel = function() {
19 self.lastTmp++;
20 return "tmp"+self.lastTmp;
21 };
22 }
23
24 constantElement(v) {
25 let S = "";
26 const mask = bigInt("FFFFFFFFFFFFFFFF", 16);
27 for (let i=0; i<this.n64; i++) {
28 if (i>0) S = S+",";
29 let shex = v.shiftRight(i*64).and(mask).toString(16);
30 while (shex.length <16) shex = "0" + shex;
31 S = S + "0x" + shex;
32 }
33 return S;
34 }
35
36}
37
38async function buildField(q, name) {
39 const builder = new ZqBuilder(q, name);
40
41 const asm = await renderFile(path.join(__dirname, "fr.asm.ejs"), builder);
42 const c = await renderFile(path.join(__dirname, "fr.c.ejs"), builder);
43 const h = await renderFile(path.join(__dirname, "fr.h.ejs"), builder);
44
45 return {asm: asm, h: h, c: c};
46}
47
48if (runningAsScript) {
49 const fs = require("fs");
50 var argv = require("yargs")
51 .usage("Usage: $0 -q [primeNum] -n [name] -oc [out .c file] -oh [out .h file]")
52 .demandOption(["q","n"])
53 .alias("q", "prime")
54 .alias("n", "name")
55 .argv;
56
57 const q = bigInt(argv.q);
58
59 const asmFileName = (argv.oc) ? argv.oc : argv.name.toLowerCase() + ".asm";
60 const hFileName = (argv.oc) ? argv.oc : argv.name.toLowerCase() + ".h";
61 const cFileName = (argv.oc) ? argv.oc : argv.name.toLowerCase() + ".c";
62
63 buildField(q, argv.name).then( (res) => {
64 fs.writeFileSync(asmFileName, res.asm, "utf8");
65 fs.writeFileSync(hFileName, res.h, "utf8");
66 fs.writeFileSync(cFileName, res.c, "utf8");
67 });
68
69} else {
70 module.exports = buildField;
71}