-
Notifications
You must be signed in to change notification settings - Fork 425
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor(scope): move unstringification of BigInts to Library from client #146
Conversation
…ient The CLI uses the `unstringifyBigInts` utility on Objects and then passes it to the library functions. When working on a webclient or using the library without the cli this leads to production of errors, one example is generating callData for Solidity Verifier, since unstringification of BigBigInts haven’t happened, the callData generated is corrupt, anyone who wants to fix this would have to read the cli to figure out what is going wrong. Two files: `plonk_verify.js` & `groth16_verify.js` are doing this unstringification in themselves already, and the CLI is doing it again making the unstringification reduntant. This PR moves the unstringification of BigInts to library files, which saves the effort for anyone consuming the library to dig deep in the CLI and then figure our what is going wrong, it also solves the reduntancy mentioned in the section above. The PR also includes the updated builds and has also passed all described library tests.
@bajpai244 I generally like this PR! However, I'm unclear if this is a breaking change for anyone that is already using any of the APIs in something like node or the browser. For example, if they were already passing a BigInt to the functions (is that supported currently?) the |
@phated glad that u like it! So, this is a non-breaking change, if we look at the description of export function unstringifyBigInts(o) {
if ((typeof(o) == "string") && (/^[0-9]+$/.test(o) )) {
return bigInt(o);
} else if ((typeof(o) == "string") && (/^0x[0-9a-fA-F]+$/.test(o) )) {
return bigInt(o);
} else if (Array.isArray(o)) {
return o.map(unstringifyBigInts);
} else if (typeof o == "object") {
const res = {};
const keys = Object.keys(o);
keys.forEach( (k) => {
res[k] = unstringifyBigInts(o[k]);
});
return res;
} else {
return o;
}
} As we can see that if a particular field is not of type string or object it simply returns it { the last else case! }, Hence if you will pass it an object that has unstringified bigInts, the function would have no effect on it! Therefore u can apply this utility as many times as u want. Here is a quick example to test this out: const { utils } = require("ffjavascript");
const crypto = require('crypto');
const assert = require('assert');
const { unstringifyBigInts, leBuff2int } = utils;
const randomBigInt = (nbytes) => leBuff2int(crypto.randomBytes(nbytes));
const main = () => {
// the num field is a BigInt
const obj = {
num: randomBigInt(31)
};
// we are unstrigifying an object with BigInts, it still works like a charm!
const unstringifiedObj = unstringifyBigInts(obj);
console.log("obj =>", obj);
console.log("unstringifiedObj =>", unstringifiedObj);
// assertion passes
assert.equal(obj.num === unstringifiedObj.num, true);
}
main(); p.s: This is already happening in the current version in |
@bajpai244 |
I'm checking with the team on whether we should drop the "big-integer" shim. |
@phated even on platforms that don't have native support this will work! Let's take a look at how "big-integer" represents BigInt if there is no native support. {
value: number | array[number],
sign: boolean,
isSmall: boolean
} Since no field of this object is of type string, hence Here is a repl that I have made: https://replit.com/@HARSHBAJPAI1/UnstringifyBigIntDemo#index.js I have manually switched off support for native bigInt in this case! You can see that even if I am applying |
This is very helpful! I wonder if the "big-integer" library is storing the value as a number because it is within the valid JS range. I thought the trick for BigInts was to store them as strings? Maybe it has an optimization for small numbers. |
@phated so, for example let's take: const obj = new bigInt("75643564363473453456342378564387956906736546456235345"); It will store {
value: [
6235345, 3654645,
9569067, 8564387,
5634237, 4734534,
3564363, 7564
],
sign: false,
isSmall: false
} Hence, none of its field will ever be of type string! |
Excellent. Thanks. Can you remove the |
@phated, I have removed all the build files from this PR 🙌 |
The CLI uses the
unstringifyBigInts
utility on Objects and then passesit to the library functions. When working on a webclient or using the library
without the cli this leads to production of errors, one example is
generating callData for Solidity Verifier, since unstringification of
BigInts haven’t happened, the callData generated is corrupt, anyone
who wants to fix this would have to read the cli to figure out what is
going wrong.
Two files:
plonk_verify.js
&groth16_verify.js
are doing thisunstringification in themselves already, and the CLI is doing it again
making the unstringification reduntant.
This PR moves the unstringification of BigInts to library files, which saves the
effort for anyone consuming the library to dig deep in the CLI and then
figure out what is going wrong, it also solves the redundancy mentioned
in the section above.
The PR also includes the updated builds and has also passed all
described library tests.