herumi / mcl

a portable and fast pairing-based cryptography library
BSD 3-Clause "New" or "Revised" License
450 stars 152 forks source link

deserializeHexStrToFr problem in mcl-wasm #59

Closed mhewett-ks closed 5 years ago

mhewett-ks commented 5 years ago

I am unable to deserialize some hex strings in mcl-wasm in the browser. The first test string is 63 hex characters so it fails due to not being an even number of characters. If I put "0" on the front to make it 64 characters, there is an error in the C code. Adding a leading space to the short string also generates an error.

How do I create an Fr number that is smaller than 32 bytes? For example, I would like mcl.deserializeHexStrToFr("07") to work. Is there an alternative method?

As a side issue, the error message is confusing. "Error: fromHexStr:length must be even 63" would be more understandable if it was "fromHexStr:length must be even; length is 63".

Code:

    let t1str = null;
        let t1 = null;
        try {
            t1str = "eca3a7bd15e08e0f6771805cbc4b8905654e9d356d5398a2aa4cbc71a55017c";
            t1 = mcl.deserializeHexStrToFr(t1str);
        } catch (ex) {
            console.log("Unable to deserialize '" + t1str + "'");
            console.log(ex);
        }

        try {
            t1str = "0eca3a7bd15e08e0f6771805cbc4b8905654e9d356d5398a2aa4cbc71a55017c";
            t1 = mcl.deserializeHexStrToFr(t1str);
        } catch (ex) {
            console.log("Unable to deserialize '" + t1str + "'");
            console.log(ex);
        }

Output:

mcl initialized to BLS12-381.

test.js:23974 Unable to deserialize 'eca3a7bd15e08e0f6771805cbc4b8905654e9d356d5398a2aa4cbc71a55017c'
test.js:23975 Error: fromHexStr:length must be even 63
    at Object.exports.fromHexStr (test.js:22820)
    at exports.Fr.deserializeHexStr (test.js:22950)
    at Object.exports.deserializeHexStrToFr (test.js:23070)
    at <anonymous>:1:1

test.js:23982 Unable to deserialize '0eca3a7bd15e08e0f6771805cbc4b8905654e9d356d5398a2aa4cbc71a55017c'
test.js:23983 Error: err _wrapDeserialize
    at test.js:22856
    at exports.Fr._setter (test.js:22983)
    at exports.Fr.deserialize (test.js:23033)
    at exports.Fr.deserializeHexStr (test.js:22950)
    at Object.exports.deserializeHexStrToFr (test.js:23070)
    at <anonymous>:1:1
mhewett-ks commented 5 years ago

For further information, it throws an error on some strings because the line below in wrapDeserialize() returns 0. The prior step of parsing the hex string works correctly.

const r = func(x, pos, buf.length)

The full function is:

   const _wrapDeserialize = func => {
      return (x, buf) => {
        const pos = _malloc(buf.length)
        mod.HEAP8.set(buf, pos)
        const r = func(x, pos, buf.length)
        _free(pos)
        if (r === 0) throw new Error('err _wrapDeserialize', buf)
      }
    }
mhewett-ks commented 5 years ago

Fr test cases in addition to the "eca3..." cases mentioned above.

Successful:

080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0800000000000000000000000000000000000000000000000000000000000000
072c4d8f242453020ac81adad4173f1ab2491ecdbbbe59793b262a4014feab41f17ed370fb710380ab5b985d6318496d
072c4d8f242453020ac81adad4173f1ab2491ecdbbbe59793b262a4014feab41

For the longer strings, it only parses the first 64 hex characters, which is acceptable.

Unsuccessful:

07FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
07FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
07
herumi commented 5 years ago

I am unable to deserialize some hex strings

mcl.deserializeHexStrToFr() accepts only the string generated by Fp.serializeToHexStr(). it must be 64-byte fixed size and be in [0, p).

If you want to set a small string, then please use setStr().

a.setStr('0x7f') // hex-string with 0x-prefix
a.getStr(16)
"7f"
a.setStr("123")
a.getStr() // decimal
"123"
a.setStr('0eca3a7bd15e08e0f6771805cbc4b8905654e9d356d5398a2aa4cbc71a55017c',16) // hex-string without prefix and 16 is specified
a.getStr(16)
"eca3a7bd15e08e0f6771805cbc4b8905654e9d356d5398a2aa4cbc71a55017c"

As a side issue, the error message is confusing. "Error: fromHexStr:length must be even 63" would be more understandable

I'm sorry and I'll fix it.

mhewett-ks commented 5 years ago

Thanks for the clarifications.

mhewett-ks commented 5 years ago

One more question: Calling getStr(16) on a pairing returns 12 large numbers. I can't find any documentation on what they represent. Could you clarify exactly what the 12 numbers represent?

herumi commented 5 years ago

The target group GT of BN254 and BLS12-381 pairings is a r subgroup of the Fp^12, which is the extension field over Fp of degree 12. The 12 of BLS12-381 means the value.

see Definition of groups

mhewett-ks commented 5 years ago

I have already read that section and many other related articles. What I want to know is the exact interpretation of the 12 values. Are they a 12-element vector? Are they 4 3-element points? Are they 3 4-element vectors?

I am still learning the math behind this. I'm sure that your response "the extension field over Fp of degree 12" is the correct answer. I just don't understand exactly what it means.

Thanks for your help.

herumi commented 5 years ago

The class Fp2 has Fp member variables a, b. Fp6 has Fp2 member variables a, b, c. Fp12 has Fp6 member variables a, b.

Then the 12 Fp elements a0, ..., a11 means (((a0, a1), (a2, a3), (a4, a5)), ((a6, a7), (a8, a9), (a10, a11))).

mhewett-ks commented 5 years ago

Thank you very much.