Skip to content
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

Groth16 prover buggy draft #463

Draft
wants to merge 35 commits into
base: master
Choose a base branch
from
Draft

Groth16 prover buggy draft #463

wants to merge 35 commits into from

Conversation

Vindaar
Copy link
Collaborator

@Vindaar Vindaar commented Aug 22, 2024

Table of Contents

  1. How to compare
  2. Compare witness data & zkey coefficients data SnarkJS vs CTT
  3. buildABC results for A, B, C in SnarkJS vs CTT
  4. A, B, C after FFT (NTT) transformations SnarkJS vs CTT
  5. joinABC result SnarkJS vs CTT
  6. Proof results gA, gB, gC
  7. Where is coeff, witness also used?
  8. Compare α1, δ1
  9. Compare r, s
  10. Compare As[i] in calcAp for wt[i] * As[i]
  11. Compare MSM of wt * As

This is a work in progress Groth16 prover. While there is a way to get
correct proofs, I have not fully understood why the code produces
the right result in those circumstances.

I added 3 different {.booldefine.} variables to run one of the three
different cases.

The first case -d:CM_WN=true is the most "natural" one. zkey
coefficients are Montgomery encoded and the witness data is treated as
being in normal representation.

The second case -d:CM_WM=true reads both the coefficients and
witness data as Montgomery encoded.

In the final case -d:CMM_WN=true we treat the zkey coefficients as
doubly Montgomery encoded and the Witness data as being in normal
rep.

Why these 3 cases?

  1. That's what initially led me to get the correct results for gA and
    gB.
  2. Interpreting witness data as Montgomery encoded just seemed
    sensible, given that everything else is.
  3. In nim-groth16 there's a comment saying "zkey coefficients are
    doubly Montgomery encoded". So I tried that, to find out that
    indeed that makes it work. I just don't get it.

We will now compare a selection of different intermediate results and
try to narrow down the underlying issue.

In SnarkJS we use two functions to print the values. The inbuilt
ffjavascript.toString function, which converts values to their
normal representation and a custom asHex, which prints the internal
data as hex:

function asHex(array) {
    if (!(array instanceof Uint8Array)) {
        throw new Error('Input must be a Uint8Array, but is: ' + typeof(array));
    }
    const slice = array.slice(0, array.length);
    const bigInt = BigInt(`0x${Buffer.from(slice).toString('hex')}`);
    const result = `0x${bigInt.toString(16).padStart(array.length * 2, '0')}`;
    return result
}

(and a similar one for arrays & elliptic curve points)

Target: Match SnarkJS toString values exactly, because they
represent the normal form of the numbers. If they match we know our
numbers represent the same values.

How to compare

For SnarkJS I just added a whole bunch of stuff into my local SnarkJS
code. I can provide a diff / the whole file if someone wants to run
those.

For Constantine, all the numbers below are from running:

nim c -r -d:<C*_W* variable> tests/proof_systems/t_groth16_prover

Compare witness data & zkey coefficients data SnarkJS vs CTT

  • Let's print the coefficients & witness data after reading in
    SnarkJS

    • coefficients

      Coefficients
      asHex    = 0x5a92de414e0f2928ae165d9696ad35d4d7d7c52d79c2062c845be361c17d4d2e
      toString = 0x2259d6b14729c0fa51e1a2470908122ef13771b2da58a367974bc177a0000006
      
      asHex    = 0xa76d21ae45e6b81be3595ce3b13afe538580bb533d83498ca5444e7fb1d01602
      toString = 0xe0a77c19a07df2f666ea36f7879462e36fc76959f60cd29ac96341c4ffffffb
      
      asHex    = 0x5a92de414e0f2928ae165d9696ad35d4d7d7c52d79c2062c845be361c17d4d2e
      toString = 0x2259d6b14729c0fa51e1a2470908122ef13771b2da58a367974bc177a0000006
      
      asHex    = 0xa76d21ae45e6b81be3595ce3b13afe538580bb533d83498ca5444e7fb1d01602
      toString = 0xe0a77c19a07df2f666ea36f7879462e36fc76959f60cd29ac96341c4ffffffb
      
      asHex    = 0xa76d21ae45e6b81be3595ce3b13afe538580bb533d83498ca5444e7fb1d01602
      toString = 0xe0a77c19a07df2f666ea36f7879462e36fc76959f60cd29ac96341c4ffffffb
      
      asHex    = 0xa76d21ae45e6b81be3595ce3b13afe538580bb533d83498ca5444e7fb1d01602
      toString = 0xe0a77c19a07df2f666ea36f7879462e36fc76959f60cd29ac96341c4ffffffb
      
    • witness data

      WITNESS DATA:
      asHex    = 0x0100000000000000000000000000000000000000000000000000000000000000
      toString = 0x15ebf95182c5551cc8260de4aeb85d5d090ef5a9e111ec87dc5ba0056db1194e
      asHex    = 0xd30caef8db424a7638216078de7fe003df175c608fce2724fc063eee71fc1615
      toString = 0x28a1fab8d2e147d0c5299bb3c2ac33eddce4c404553e14186d0288ade5e12b49
      asHex    = 0x00000000000000000000000000000000000000000000000048451ed2dece9600
      toString = 0x2ef2ccfe314d0d2da42e5bda74db7b89bb6820369d3f272285d2695cbf80be93
      asHex    = 0x00000000000000000000000000000000000000000000000000a40e99156ba225
      toString = 0x6d897c505cdcade243b2f0d8738c5b5eb230d5a515406ac05bfdd10d1df4894
      asHex    = 0x000000000000000000000000000000000000000000000000c006891cf102cc04
      toString = 0x2f6afd58eb96f3cc61aa3ada4cff818e8c77ee567c43e74df1615320dbfde8b0
      asHex    = 0xc0f17fd031eee0c09eb43091d22aa608073c1d9dcd808e9863b3ecf829d2cc2d
      toString = 0x162b94328f9b883b4b1a933652200000000000000000000000000000000000
      
  • Let's print coefficients and witness data for the 3 different
    cases

    • CMWN

      WITNESS DATA:
      0 = 0x0000000000000000000000000000000000000000000000000000000000000001
      1 = 0x1516fc71ee3e06fc2427ce8f605c17df03e07fde78602138764a42dbf8ae0cd3
      2 = 0x0096ceded21e4548000000000000000000000000000000000000000000000000
      3 = 0x25a26b15990ea400000000000000000000000000000000000000000000000000
      4 = 0x04cc02f11c8906c0000000000000000000000000000000000000000000000000
      5 = 0x2dccd229f8ecb363988e80cd9d1d3c0708a62ad29130b49ec0e0ee31d07ff1c0
      Coef i = 0 = 0x2259d6b14729c0fa51e1a2470908122ef13771b2da58a367974bc177a0000006
      Coef i = 1 = 0x0e0a77c19a07df2f666ea36f7879462e36fc76959f60cd29ac96341c4ffffffb
      Coef i = 2 = 0x2259d6b14729c0fa51e1a2470908122ef13771b2da58a367974bc177a0000006
      Coef i = 3 = 0x0e0a77c19a07df2f666ea36f7879462e36fc76959f60cd29ac96341c4ffffffb
      Coef i = 4 = 0x0e0a77c19a07df2f666ea36f7879462e36fc76959f60cd29ac96341c4ffffffb
      Coef i = 5 = 0x0e0a77c19a07df2f666ea36f7879462e36fc76959f60cd29ac96341c4ffffffb
      
      • Witness data matches internal representation (asHex) up to
        endianness. Implies it's wrong.
      • Matches coefficients in toString
    • CMWM

      WITNESS DATA:
      0 = 0x15ebf95182c5551cc8260de4aeb85d5d090ef5a9e111ec87dc5ba0056db1194e
      1 = 0x28a1fab8d2e147d0c5299bb3c2ac33eddce4c404553e14186d0288ade5e12b49
      2 = 0x2ef2ccfe314d0d2da42e5bda74db7b89bb6820369d3f272285d2695cbf80be93
      3 = 0x06d897c505cdcade243b2f0d8738c5b5eb230d5a515406ac05bfdd10d1df4894
      4 = 0x2f6afd58eb96f3cc61aa3ada4cff818e8c77ee567c43e74df1615320dbfde8b0
      5 = 0x00162b94328f9b883b4b1a933652200000000000000000000000000000000000
      Coef i = 0 = 0x2259d6b14729c0fa51e1a2470908122ef13771b2da58a367974bc177a0000006
      Coef i = 1 = 0x0e0a77c19a07df2f666ea36f7879462e36fc76959f60cd29ac96341c4ffffffb
      Coef i = 2 = 0x2259d6b14729c0fa51e1a2470908122ef13771b2da58a367974bc177a0000006
      Coef i = 3 = 0x0e0a77c19a07df2f666ea36f7879462e36fc76959f60cd29ac96341c4ffffffb
      Coef i = 4 = 0x0e0a77c19a07df2f666ea36f7879462e36fc76959f60cd29ac96341c4ffffffb
      Coef i = 5 = 0x0e0a77c19a07df2f666ea36f7879462e36fc76959f60cd29ac96341c4ffffffb
      
      • Witness data matches toString
      • Coefficients match toString

      -> implies we read the data correctly!

    • CMMWN

      WITNESS DATA:
      0 = 0x0000000000000000000000000000000000000000000000000000000000000001
      1 = 0x1516fc71ee3e06fc2427ce8f605c17df03e07fde78602138764a42dbf8ae0cd3
      2 = 0x0096ceded21e4548000000000000000000000000000000000000000000000000
      3 = 0x25a26b15990ea400000000000000000000000000000000000000000000000000
      4 = 0x04cc02f11c8906c0000000000000000000000000000000000000000000000000
      5 = 0x2dccd229f8ecb363988e80cd9d1d3c0708a62ad29130b49ec0e0ee31d07ff1c0
      Coef i = 0 = 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000
      Coef i = 1 = 0x0000000000000000000000000000000000000000000000000000000000000001
      Coef i = 2 = 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000
      Coef i = 3 = 0x0000000000000000000000000000000000000000000000000000000000000001
      Coef i = 4 = 0x0000000000000000000000000000000000000000000000000000000000000001
      Coef i = 5 = 0x0000000000000000000000000000000000000000000000000000000000000001
      
      • Of course same as CM_WN for witness data, matches
      • Coefficients are different. What's somewhat interesting is
        that 4 of the 6 are 1.

buildABC results for A, B, C in SnarkJS vs CTT

  • SnarkJS output for A, B, C calculations in buildABC1:

    OUTBUF A (asHex):     0x44c652ba2192dd433f443406bdc589d6e5de1667c03c1a0cad178388ef6c2f1b
    OUTBUF A (toString):  0x2fcd7f940f135ae1b85045b68181585d2833e84879b9709143e1f593f0000001
    OUTBUF B (asHex):     0xeabd81f5ff6dbc23b15ef41cd26ca542efa8e3eb34718bcbe952fbb804ba3d1d
    OUTBUF B (toString):  0x25a26b15990ea400000000000000000000000000000000000000000000000000
    OUTBUF C (asHex):     0x7be6f54dafe636fd7f532f6608a7c58180b71c783f5807d9cd4815f1c73e7f22
    OUTBUF C (toString):  0x2977c48e844ecc61fc1c4e8e4641c561f8dbd75e888bbf2830107621f800e41
    
    OUTBUF A (asHex):     0x7be6f54dafe636fd7f532f6608a7c58180b71c783f5807d9cd4815f1c73e7f22
    OUTBUF A (toString):  0x2977c48e844ecc61fc1c4e8e4641c561f8dbd75e888bbf2830107621f800e41
    OUTBUF B (asHex):     0x397d67b1b594cd0e61a73253c9adad73cf8140c1a6753f0d7444c44d7790ce13
    OUTBUF B (toString):  0x4cc02f11c8906c0000000000000000000000000000000000000000000000000
    OUTBUF C (asHex):     0x2c40094b65fc52225f54c0003947e2a8e95723733130628214767d54655dab08
    OUTBUF C (toString):  0x1b4d5200f2f3992d942877272125407e2453686a01594f58cd97b2b7f751f32e
    
    OUTBUF A (asHex):     0xfbffff4f1c3496ac29cd609f9576fc362e4679786fa36e662fdf079ac1770a0e
    OUTBUF A (toString):  0x1
    OUTBUF B (asHex):     0x0000000000000000000000000000000000000000000000000000000000000000
    OUTBUF B (toString):  0x0
    OUTBUF C (asHex):     0x0000000000000000000000000000000000000000000000000000000000000000
    OUTBUF C (toString):  0x0
    
    OUTBUF A (asHex):     0xd5bff6a42ef98e21321cf9780fa1517f73005e0e8515ee35152ab48c0df1b827
    OUTBUF A (toString):  0x1516fc71ee3e06fc2427ce8f605c17df03e07fde78602138764a42dbf8ae0cd3
    OUTBUF B (asHex):     0x0000000000000000000000000000000000000000000000000000000000000000
    OUTBUF B (toString):  0x0
    OUTBUF C (asHex):     0x0000000000000000000000000000000000000000000000000000000000000000
    OUTBUF C (toString):  0x0
    
  • CTT output for A, B, C for the different cases

    • CMWN

      OUTBUF A: 0x1b2f6cef888317ad0c1a3cc06716dee5d689c5bd0634443f43dd9221ba52c644
      OUTBUF B: 0x1d3dba04b8fb52e9cb8b7134ebe3a8ef42a56cd21cf45eb123bc6dfff581bdea
      OUTBUF C: 0x2a8abc20ddeaaaed1dca3166bba9ed60108959466966042fc950a3f418d0b951
      OUTBUF A: 0x227f3ec7f11548cdd907583f781cb78081c5a708662f537ffd36e6af4df5e67b
      OUTBUF B: 0x13ce90774dc444740d3f75a6c14081cf73adadc95332a7610ecd94b5b1677d39
      OUTBUF C: 0x180f5f450e03d2f88e6718296c5a0c6cfb158eea0ae55fc8cd585204dae52cbc
      OUTBUF A: 0x0e0a77c19a07df2f666ea36f7879462e36fc76959f60cd29ac96341c4ffffffb
      OUTBUF B: 0x0000000000000000000000000000000000000000000000000000000000000000
      OUTBUF C: 0x0000000000000000000000000000000000000000000000000000000000000000
      OUTBUF A: 0x27b8f10d8cb42a1535ee15850e5e00737f51a10f78f91c32218ef92ea4f6bfd5
      OUTBUF B: 0x0000000000000000000000000000000000000000000000000000000000000000
      OUTBUF C: 0x0000000000000000000000000000000000000000000000000000000000000000
      
      • A, B match SnarkJS in internal representation and inverted
        endianness
      • C therefore does not match, because numbers in normal rep
        are different
    • CMWM

      OUTBUF A: 0x2fcd7f940f135ae1b85045b68181585d2833e84879b9709143e1f593f0000001
      OUTBUF B: 0x25a26b15990ea400000000000000000000000000000000000000000000000000
      OUTBUF C: 0x02977c48e844ecc61fc1c4e8e4641c561f8dbd75e888bbf2830107621f800e41
      OUTBUF A: 0x02977c48e844ecc61fc1c4e8e4641c561f8dbd75e888bbf2830107621f800e41
      OUTBUF B: 0x04cc02f11c8906c0000000000000000000000000000000000000000000000000
      OUTBUF C: 0x1b4d5200f2f3992d942877272125407e2453686a01594f58cd97b2b7f751f32e
      OUTBUF A: 0x0000000000000000000000000000000000000000000000000000000000000001
      OUTBUF B: 0x0000000000000000000000000000000000000000000000000000000000000000
      OUTBUF C: 0x0000000000000000000000000000000000000000000000000000000000000000
      OUTBUF A: 0x1516fc71ee3e06fc2427ce8f605c17df03e07fde78602138764a42dbf8ae0cd3
      OUTBUF B: 0x0000000000000000000000000000000000000000000000000000000000000000
      OUTBUF C: 0x0000000000000000000000000000000000000000000000000000000000000000
      
      • All A, B and C match exactly.
    • CMMWN

      OUTBUF A: 0x2fcd7f940f135ae1b85045b68181585d2833e84879b9709143e1f593f0000001
      OUTBUF B: 0x25a26b15990ea400000000000000000000000000000000000000000000000000
      OUTBUF C: 0x02977c48e844ecc61fc1c4e8e4641c561f8dbd75e888bbf2830107621f800e41
      OUTBUF A: 0x02977c48e844ecc61fc1c4e8e4641c561f8dbd75e888bbf2830107621f800e41
      OUTBUF B: 0x04cc02f11c8906c0000000000000000000000000000000000000000000000000
      OUTBUF C: 0x1b4d5200f2f3992d942877272125407e2453686a01594f58cd97b2b7f751f32e
      OUTBUF A: 0x0000000000000000000000000000000000000000000000000000000000000001
      OUTBUF B: 0x0000000000000000000000000000000000000000000000000000000000000000
      OUTBUF C: 0x0000000000000000000000000000000000000000000000000000000000000000
      OUTBUF A: 0x1516fc71ee3e06fc2427ce8f605c17df03e07fde78602138764a42dbf8ae0cd3
      OUTBUF B: 0x0000000000000000000000000000000000000000000000000000000000000000
      OUTBUF C: 0x0000000000000000000000000000000000000000000000000000000000000000
      
      • Surprisingly all of them also match. Given that A, B are
        just coeff * witness, does that imply that in this context the
        Montgomery rep R commutes between the two scalars?

A, B, C after FFT (NTT) transformations SnarkJS vs CTT

  • SnarkJS:

    A after itf?
    asHex    = 0x6d8ae26488f7a30dcd9aa5d3d75c8eab4dbe2559a17ce7bc1e24f619da1fe104
    toString = 0x188d86b0d9e4e4c5a616c9a110e7548601731a4a1e8b9a8c3a833e92412b7621
    asHex    = 0x4c3828dd3c8b3c7dec442812dd352efdc0cef1d75984fdd4668f6b53e07aa11a
    toString = 0x28facbebe8cf7298951a51ee088a4b96bf46bfc2bd33af6624cea9ea92c16a65
    asHex    = 0x168d9a4211ed5d26c5c89241577c2d50e73a73bdda53ad495467855b28698c0c
    toString = 0x292faed2c15f4891747d3aee64f23d54983900dfdff55361b208042385d1d2ba
    asHex    = 0xbf1c9a88b140191a0b68a3e3158d7fedb4bcfef567b39bedbbae3bf630c2fe16
    toString = 0xd28455242b44ede04dbc867c95f077e1ae332f898a720f96fb548c59e6f67d7
    ======================
    B after itf?
    asHex    = 0xee2b238aab22b591df30ed5a99056557655fd6e74a14f928419483d3bf805603
    toString = 0x268a7734f4bb36808c58d55cd0448e94986a4b5b0c421c3dc33d4da9a556c51a
    asHex    = 0x7964679fe01c74d97f2143c42e991c32f48e0b88e8a7990b46df5604148be627
    toString = 0xf91f92db613330bb9936d259475b45914a6fb7dae1b6d0093fbee2a55809692
    asHex    = 0x67d788b976bcd5c4632bca0277201864e45756737051d5593834381669dd9e00
    toString = 0x67a53e9548dc06371a964781f5480e193fe2f3ddbc5ccd98fee909bd4fc7284
    asHex    = 0x55d3d5c3b2068b024f882c4e5c5bb9c880e4ebc937d9624a9eefac183f613005
    toString = 0x1e3bf82d976d20fa00ba9ebbfd72948de7247231e3961a795cba2924202c31d1
    ======================
    C after itf?
    asHex    = 0x9996c71584995406042d3a5066abe5da8994e5e5e616c34923f2d7019ebcab11
    toString = 0x1ec6e506485fbd44dce5720bf9d3251db03e32e0d370064613920f865badb80a
    asHex    = 0xc82a18aa5605ad8395169f62af79a6dbb5eac994bae46ba89e2e108c52e3970f
    toString = 0x2e47bf408db31e8beb138c01cc0c4e34c59eeedeb6a7bdd84871eddd24d9d67d
    asHex    = 0x9a492a3881d4ab13aec36919e81bd09a24456800e1c132b39ba12bdc5b685a30
    toString = 0x15f37cc9007bf98c4a897fbff7ab64c6247ab5e52b3d5cfa844d29275eccc00
    asHex    = 0xad1bf5904c65bec5281166148c957f0163a3a9f1a410586eae9cb0bc53e2f009
    toString = 0x303f8f1c37812add97e931734331e3efbc2429530089527fd413d54c005da6ea
    
  • CTT output for A, B, C after itf

    • CMWN

      A after itf? 0x04e11fda19f6241ebce77ca15925be4dab8e5cd7d3a59acd0da3f78864e28a6d
      A after itf? 0x1aa17ae0536b8f66d4fd8459d7f1cec0fd2e35dd122844ec7d3c8b3cdd28384c
      A after itf? 0x0c8c69285b85675449ad53dabd733ae7502d7c574192c8c5265ded11429a8d16
      A after itf? 0x16fec230f63baebbed9bb367f5febcb4ed7f8d15e3a3680b1a1940b1889a1cbf
      B after itf? 0x035680bfd383944128f9144ae7d65f65576505995aed30df91b522ab8a232bee
      B after itf? 0x27e68b140456df460b99a7e8880b8ef4321c992ec443217fd9741ce09f676479
      B after itf? 0x009edd691638343859d55170735657e46418207702ca2b63c4d5bc76b988d767
      B after itf? 0x0530613f18acef9e4a62d937c9ebe480c8b95b5c4e2c884f028b06b2c3d5d355
      C after itf? 0x2c4461e5bd4bc46dc8e712e57c892741663658a9410ad134bc2a98632b3d8f3d
      C after itf? 0x296282737b8f5441bc82824db76705e40288effa7a8c6ccc7f2eb34545c8779b
      C after itf? 0x2438eb44fe0595cf23d54eb38fc6bc06946aecb579a99480f8f4db1a95635524
      C after itf? 0x2982e8ad77710fba7392f116674fc15b5edc8368327d7298ea1eba5dcd4c8a13
      
      • A, B match SnarkJS in the internal representation (asHex)
        again
      • C as expected does not match
    • CMWM

      A after itf? 0x188d86b0d9e4e4c5a616c9a110e7548601731a4a1e8b9a8c3a833e92412b7621
      A after itf? 0x28facbebe8cf7298951a51ee088a4b96bf46bfc2bd33af6624cea9ea92c16a65
      A after itf? 0x292faed2c15f4891747d3aee64f23d54983900dfdff55361b208042385d1d2ba
      A after itf? 0x0d28455242b44ede04dbc867c95f077e1ae332f898a720f96fb548c59e6f67d7
      B after itf? 0x268a7734f4bb36808c58d55cd0448e94986a4b5b0c421c3dc33d4da9a556c51a
      B after itf? 0x0f91f92db613330bb9936d259475b45914a6fb7dae1b6d0093fbee2a55809692
      B after itf? 0x067a53e9548dc06371a964781f5480e193fe2f3ddbc5ccd98fee909bd4fc7284
      B after itf? 0x1e3bf82d976d20fa00ba9ebbfd72948de7247231e3961a795cba2924202c31d1
      C after itf? 0x1ec6e506485fbd44dce5720bf9d3251db03e32e0d370064613920f865badb80a
      C after itf? 0x2e47bf408db31e8beb138c01cc0c4e34c59eeedeb6a7bdd84871eddd24d9d67d
      C after itf? 0x015f37cc9007bf98c4a897fbff7ab64c6247ab5e52b3d5cfa844d29275eccc00
      C after itf? 0x303f8f1c37812add97e931734331e3efbc2429530089527fd413d54c005da6ea
      
      • A, B match exactly, and (thus?) C also matches exactly
    • CMMWN

      A after itf? 0x188d86b0d9e4e4c5a616c9a110e7548601731a4a1e8b9a8c3a833e92412b7621
      A after itf? 0x28facbebe8cf7298951a51ee088a4b96bf46bfc2bd33af6624cea9ea92c16a65
      A after itf? 0x292faed2c15f4891747d3aee64f23d54983900dfdff55361b208042385d1d2ba
      A after itf? 0x0d28455242b44ede04dbc867c95f077e1ae332f898a720f96fb548c59e6f67d7
      B after itf? 0x268a7734f4bb36808c58d55cd0448e94986a4b5b0c421c3dc33d4da9a556c51a
      B after itf? 0x0f91f92db613330bb9936d259475b45914a6fb7dae1b6d0093fbee2a55809692
      B after itf? 0x067a53e9548dc06371a964781f5480e193fe2f3ddbc5ccd98fee909bd4fc7284
      B after itf? 0x1e3bf82d976d20fa00ba9ebbfd72948de7247231e3961a795cba2924202c31d1
      C after itf? 0x1ec6e506485fbd44dce5720bf9d3251db03e32e0d370064613920f865badb80a
      C after itf? 0x2e47bf408db31e8beb138c01cc0c4e34c59eeedeb6a7bdd84871eddd24d9d67d
      C after itf? 0x015f37cc9007bf98c4a897fbff7ab64c6247ab5e52b3d5cfa844d29275eccc00
      C after itf? 0x303f8f1c37812add97e931734331e3efbc2429530089527fd413d54c005da6ea
      
      • They also all still match. Expected, because A, B, C from
        buildABC were identical.

joinABC result SnarkJS vs CTT

  • SnarkJS:

    jabc?
    asHex    = 0x605d5288cce8f5ca518235fa96010749c537f41d8875975dc8261dcbdce71110
    toString = 0x23b0b21217dcd8e8c9808b28b3531b264a17a334177163cf4e57fa4e6d19783e
    asHex    = 0x8452b11db5a5f336ea4f0b301590df426d002f269bae51b23800f0b3890d231c
    toString = 0x23e816749389d6618b74c0e0ad1a1c26fdd9e3dfcb4db750c708c71faa3a0683
    asHex    = 0xd920cbdcecbb1dd0b210ee1cf937bd6d3e1a4f6be18a92abb92893b465b14627
    toString = 0x24d41473417511364a49a2b4e48ceaf65c0f5f34538c7b8d9cb5eb3067f59aaa
    asHex    = 0xfe023328b40e664fb4d7b210beae81117b6d32bfb5c96a0d96b7efdbf2ac0a23
    toString = 0xb96bc8a3a65b32bd752d91f407cfe30456a5ff0f1f0cc92664c6a126cc28eff
    
  • CTT output for joinABC

    • CMWN

      JABC? 0x122e69488ced84710eafe76323e27ad61246eceb95ae0b01cf969b7b93b00eed
      JABC? 0x2298fa8d5ad28f7bf1c798dcb26550cb4b097f6d939dcb0ab303a6a94df530b4
      JABC? 0x11b16099044bdbf70ecd02173afe4c234ac8ab04d71c8d38b61685add73b0945
      JABC? 0x079d92184d30f29397db195a80f27efbfa1b55bc39585e19fe5f772957fa02f4
      
      • Completely different. Expected, because C was wrong in buildABC
    • CMWM

      JABC? 0x1011e7dccb1d26c85d9775881df437c549070196fa358251caf5e8cc88525d60
      JABC? 0x1c230d89b3f00038b251ae9b262f006d42df9015300b4fea36f3a5b51db15284
      JABC? 0x2746b165b49328b9ab928ae16b4f1a3e6dbd37f91cee10b2d01dbbecdccb20d9
      JABC? 0x230aacf2dbefb7960d6ac9b5bf326d7b1181aebe10b2d7b44f660eb4283302fe
      
      • Huh, no match? But buildABC was the same? join ABC should
        just be:
        A[i] * B[i] - C[i]
    • CMMWN

      JABC? 0x1011e7dccb1d26c85d9775881df437c549070196fa358251caf5e8cc88525d60
      JABC? 0x1c230d89b3f00038b251ae9b262f006d42df9015300b4fea36f3a5b51db15284
      JABC? 0x2746b165b49328b9ab928ae16b4f1a3e6dbd37f91cee10b2d01dbbecdccb20d9
      JABC? 0x230aacf2dbefb7960d6ac9b5bf326d7b1181aebe10b2d7b44f660eb4283302fe
      
      • Same numbers ase CM_WM, so no match either.

None of these match.

Proof results gA, gB, gC

  • Proof from SnarkJS:

    {
     "pi_a": [
      "5525629793372463776337933283524928112323589665400780041477380790923758613749",
      "21229177076048503863699135039723099340209138028149442778064006577287317302601",
      "1"
     ],
     "pi_b": [
      [
       "10113559933709853115219982658131344715329670532374721861173670433756614595086",
       "748111067660143353202076805159132563350177510079329482395824347599610874338"
      ],
      [
       "14193926223452546125681093394065339196897041249946578591171606543100010486627",
       "871256420758854731396810855688710623510558493821614150596755347032202324148"
      ],
      [
       "1",
       "0"
      ]
     ],
     "pi_c": [
      "18517653609733492682442099361591955563405567929398531111532682405176646276349",
      "17315036348446251361273519572420522936369550153340386126725970444173389652255",
      "1"
     ],
     "protocol": "groth16",
     "curve": "bn128"
    }%
    
  • CTT proofs

    • CMWN

      A_p#10 = EC_ShortW_Aff[Fp[BN254_Snarks], G1](
        x: 05525629793372463776337933283524928112323589665400780041477380790923758613749,
        y: 21229177076048503863699135039723099340209138028149442778064006577287317302601
      )
      ------------------------------
      B_p#10 = EC_ShortW_Aff[Fp2[BN254_Snarks], G2](
        x: Fp2(
        c0: 10113559933709853115219982658131344715329670532374721861173670433756614595086,
        c1: 00748111067660143353202076805159132563350177510079329482395824347599610874338),
        y: Fp2(
        c0: 14193926223452546125681093394065339196897041249946578591171606543100010486627,
        c1: 00871256420758854731396810855688710623510558493821614150596755347032202324148)
      )
      ------------------------------
      C_p#10 = EC_ShortW_Aff[Fp[BN254_Snarks], G1](
        x: 12524785304069290509448413767699932740828656355192528146073107099016111123885,
        y: 03285628268350284309020370879913195676683658549907819489051412512121524349470
      )
      
      • A and B match! They are independent of all the buildABC,
        joinABC logic
      • C does not match.
    • CMWM

      A_p#10 = EC_ShortW_Aff[Fp[BN254_Snarks], G1](
        x: 04968880331005830054646557787993338092114034965196983100047029494587651738084,
        y: 00709771911297310656849216223315047376245021728823914080489321084959093177901
      )
      ------------------------------
      B_p#10 = EC_ShortW_Aff[Fp2[BN254_Snarks], G2](
        x: Fp2(
        c0: 04424047900546469720369595125488506408085988436635602562519845599653120103999,
        c1: 04364074914134911307849088448662118984187797875872322215138286861730543951747),
        y: Fp2(
        c0: 00589613272669639289214636029065744605391449574601529901028020727341562216231,
        c1: 02711113291137838075469765998865936969663195682986111663908855262369191180233)
      )
      ------------------------------
      C_p#10 = EC_ShortW_Aff[Fp[BN254_Snarks], G1](
        x: 04299112160807009304960473994183814690258821862820010439762399455113089654848,
        y: 16151241800928901395926210456440348931913937753770724844008742709570659843866
      )
      
      • None match!
    • CMMWN

      A_p#10 = EC_ShortW_Aff[Fp[BN254_Snarks], G1](
        x: 05525629793372463776337933283524928112323589665400780041477380790923758613749,
        y: 21229177076048503863699135039723099340209138028149442778064006577287317302601
      )
      ------------------------------
      B_p#10 = EC_ShortW_Aff[Fp2[BN254_Snarks], G2](
        x: Fp2(
        c0: 10113559933709853115219982658131344715329670532374721861173670433756614595086,
        c1: 00748111067660143353202076805159132563350177510079329482395824347599610874338),
        y: Fp2(
        c0: 14193926223452546125681093394065339196897041249946578591171606543100010486627,
        c1: 00871256420758854731396810855688710623510558493821614150596755347032202324148)
      )
      ------------------------------
      C_p#10 = EC_ShortW_Aff[Fp[BN254_Snarks], G1](
        x: 18517653609733492682442099361591955563405567929398531111532682405176646276349,
        y: 17315036348446251361273519572420522936369550153340386126725970444173389652255
      )
      
      • They all match! Given that joinABC is different from
        SnarkJS, but the same as CM_WM, it implies it must come from
        another occurrence of coeff or witness, where the "other"
        version is "correct".

Despite joinABC not matching, the proof for CMM_WN does match?!

Where is coeff, witness also used?

  • I think coeff is used nowhere else, right?
    -> Indeed, only usage in buildABC
  • Where is witness used?
    -> Calculation of calcAp, calcBp, calcB1, buildABC and the
    private elements entering proof for gC

DONE Compare α1, δ1

  • SnarkJS

    α1 =
    x (toString): 773b8e1e302811615bb36769814191e11256b6ba43ac356c68326285e50129e
    y (toString): a40ed3a4640837692ffa1e912fdad79e5ed8b0f60a46ccf7440df3f6b05c02e
    δ1 =
    x (toString): 2dc2f89a3a63fa0740b62edb40ee49242559be9a32c14b7790e048f11c12c09f
    y (toString): 12860932f6b54710cae28f4cf543dd8680d388ccfff47ba89ca1f06b10c3626e
    
  • CMWN, CMWM, CMMWN are all identical here:

    α1 : EC_ShortW_Aff[Fp[BN254_Snarks], G1](
      x: 0x0773b8e1e302811615bb36769814191e11256b6ba43ac356c68326285e50129e,
      y: 0x0a40ed3a4640837692ffa1e912fdad79e5ed8b0f60a46ccf7440df3f6b05c02e
    )
    δ1 : EC_ShortW_Aff[Fp[BN254_Snarks], G1](
      x: 0x2dc2f89a3a63fa0740b62edb40ee49242559be9a32c14b7790e048f11c12c09f,
      y: 0x12860932f6b54710cae28f4cf543dd8680d388ccfff47ba89ca1f06b10c3626e
    )
    
    • Identical to SnarkJS

DONE Compare r, s

  • SnarkJS:

    r:
    asHex    = 0x8f3776492a733c4d5fd12990fa898a47b0f2bae8b31e58ffc6a1b696dc952113
    toString = 0x19e099669eeea556b39db92a94a971ebecddf5d71c677bdc5f4b2c6ae0dcca43
    s:
    asHex    = 0xd569691b81f98b9edd4425a33b47136c3c99b79c1994250955cdfaf6848ef424
    toString = 0x2eeb9f84517969468eb4625a5f5c73987828e9ef842ffa750bde0fc6e7290e56
    
  • CTT (all cases the same):

    r = 0x19e099669eeea556b39db92a94a971ebecddf5d71c677bdc5f4b2c6ae0dcca43
    s = 0x2eeb9f84517969468eb4625a5f5c73987828e9ef842ffa750bde0fc6e7290e56
    

Compare As[i] in calcAp for wt[i] * As[i]

  • SnarkJS:

    x (toString): 2ff61f748b95807f742d724af7b5e5c6bbbe32377c9e2929b8a847a0e19a081a
    y (toString): fec5c4f42d7e1b68bc6c610dfd94a2a784daae63f2b0d25621ca55704343f1b
    x (toString): 27efece16fce27bf382263c2554f07364f76ec65e290e33fd633d74d8ddc2bb5
    y (toString): a2e4dec302bfcfd94488cf6df8ddd09db048b1eddc35a66964c24f6ec85d1c2
    x (toString): 20f3c8aff50add131d4fd34bc093882e26872b6e53332988334c8cf463d91dc2
    y (toString): 2ddafdebb26ba0e0abefc46848b20deb199f882532d3396a69fa2695757783e8
    x (toString): 0
    y (toString): 1
    x (toString): 0
    y (toString): 1
    x (toString): 73184caf2eb46c8735dfe490f51f0f7c7d021cd0a8a7d22f4cc5dd7487660ef
    y (toString): 13efa7f5062f2de3b2084620ed2b79fd22caa1dc935840322b94787c00090dd5
    
  • CTT (all cases the same):

    i = 0 As[i] = EC_ShortW_Aff[Fp[BN254_Snarks], G1](
      x: 0x2ff61f748b95807f742d724af7b5e5c6bbbe32377c9e2929b8a847a0e19a081a,
      y: 0x0fec5c4f42d7e1b68bc6c610dfd94a2a784daae63f2b0d25621ca55704343f1b
    )
    i = 1 As[i] = EC_ShortW_Aff[Fp[BN254_Snarks], G1](
      x: 0x27efece16fce27bf382263c2554f07364f76ec65e290e33fd633d74d8ddc2bb5,
      y: 0x0a2e4dec302bfcfd94488cf6df8ddd09db048b1eddc35a66964c24f6ec85d1c2
    )
    i = 2 As[i] = EC_ShortW_Aff[Fp[BN254_Snarks], G1](
      x: 0x20f3c8aff50add131d4fd34bc093882e26872b6e53332988334c8cf463d91dc2,
      y: 0x2ddafdebb26ba0e0abefc46848b20deb199f882532d3396a69fa2695757783e8
    )
    i = 3 As[i] = EC_ShortW_Aff[Fp[BN254_Snarks], G1](
      x: 0x0000000000000000000000000000000000000000000000000000000000000000,
      y: 0x0000000000000000000000000000000000000000000000000000000000000000
    )
    i = 4 As[i] = EC_ShortW_Aff[Fp[BN254_Snarks], G1](
      x: 0x0000000000000000000000000000000000000000000000000000000000000000,
      y: 0x0000000000000000000000000000000000000000000000000000000000000000
    )
    i = 5 As[i] = EC_ShortW_Aff[Fp[BN254_Snarks], G1](
      x: 0x073184caf2eb46c8735dfe490f51f0f7c7d021cd0a8a7d22f4cc5dd7487660ef,
      y: 0x13efa7f5062f2de3b2084620ed2b79fd22caa1dc935840322b94787c00090dd5
    )
    
    • They match exactly.

Compare MSM of wt * As

From the fact that wt and As are equivalent for CM_WM the MSM
portion of g^A should be identical only in that case?

  • SnarkJS

    g^A MSM =
    x (toString): 13168a05dc59f9181bae8e789ee468ee4aba2c55920d2b300eb35bb1f1023303
    y (toString): 273a14ecec92c0c2cb5137fa8f06a158743d133069ebb142715e113cb262f8b3
    
  • CTT

    • CMWN

      g^A MSM = EC_ShortW_Jac[Fp[BN254_Snarks], G1](
        x: 0x13168a05dc59f9181bae8e789ee468ee4aba2c55920d2b300eb35bb1f1023303,
        y: 0x273a14ecec92c0c2cb5137fa8f06a158743d133069ebb142715e113cb262f8b3
      )
      
      • They are the same oO, match
    • CMWM

      g^A MSM = EC_ShortW_Jac[Fp[BN254_Snarks], G1](
        x: 0x0983ee974b463d46de7fbed7958404de97f2551da7171cd225c571ddb4873fc8,
        y: 0x2b1ab9e7ed895b288eb27658be20840da78a7c1a31718746eea85115aaed4fac
      )
      
      • They differ. What?
    • CMMWM, should be the same as CMWN

      g^A MSM = EC_ShortW_Jac[Fp[BN254_Snarks], G1](
        x: 0x13168a05dc59f9181bae8e789ee468ee4aba2c55920d2b300eb35bb1f1023303,
        y: 0x273a14ecec92c0c2cb5137fa8f06a158743d133069ebb142715e113cb262f8b3
      )
      
      • Indeed the same, and matches.

So why does CM_WM not yield the right result if both inputs are
identical?

Vindaar added 30 commits July 12, 2024 14:15
The code previously accidentally only return 3 for the case 5.
Otherwise when performing operations on EC points in Jacobian,
depending on import these can be missing.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant