LCOV - code coverage report
Current view: top level - flamenco/runtime/program/zksdk/instructions - fd_zksdk_ciphertext_ciphertext_equality.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 76 102 74.5 %
Date: 2024-11-13 11:58:15 Functions: 3 3 100.0 %

          Line data    Source code
       1             : #include "../fd_zksdk_private.h"
       2             : 
       3             : static inline void
       4             : ciphertext_ciphertext_equality_transcript_init( fd_zksdk_transcript_t *                 transcript,
       5          63 :                                                 fd_zksdk_ciph_ciph_eq_context_t const * context ) {
       6          63 :   fd_zksdk_transcript_init( transcript, FD_TRANSCRIPT_LITERAL("ciphertext-ciphertext-equality-instruction") );
       7          63 :   fd_zksdk_transcript_append_pubkey    ( transcript, FD_TRANSCRIPT_LITERAL("first-pubkey"),      context->pubkey1 );
       8          63 :   fd_zksdk_transcript_append_pubkey    ( transcript, FD_TRANSCRIPT_LITERAL("second-pubkey"),     context->pubkey2 );
       9          63 :   fd_zksdk_transcript_append_ciphertext( transcript, FD_TRANSCRIPT_LITERAL("first-ciphertext"),  context->ciphertext1 );
      10          63 :   fd_zksdk_transcript_append_ciphertext( transcript, FD_TRANSCRIPT_LITERAL("second-ciphertext"), context->ciphertext2 );
      11          63 : }
      12             : 
      13             : /* https://github.com/anza-xyz/agave/blob/v2.0.1/zk-sdk/src/sigma_proofs/ciphertext_ciphertext_equality.rs#L136 */
      14             : static inline int
      15             : fd_zksdk_verify_proof_ciphertext_ciphertext_equality(
      16             :   fd_zksdk_ciph_ciph_eq_proof_t const * proof,
      17             :   uchar const                           pubkey1    [ 32 ],
      18             :   uchar const                           pubkey2    [ 32 ],
      19             :   uchar const                           ciphertext1[ 64 ],
      20             :   uchar const                           ciphertext2[ 64 ],
      21          63 :   fd_zksdk_transcript_t *               transcript ) {
      22             :   /*
      23             :     We store points and scalars in the following arrays:
      24             : 
      25             :         points  scalars
      26             :     0   G        z_x (w + ww)
      27             :     1   H       -c + z_r ww
      28             :     2   P1       z_s
      29             :     3   D1       z_s w
      30             :     4   Y_1     -w
      31             :     5   C1      -w c
      32             :     6   Y_2     -ww
      33             :     7   C2      -ww c
      34             :     8   Y_3     -www
      35             :     9   D2      -www c
      36             :    10   P2       www z_r
      37             :    ------------------------ MSM
      38             :         Y_0
      39             :   */
      40             : 
      41             :   /* Validate all inputs */
      42          63 :   uchar scalars[ 11 * 32 ];
      43          63 :   fd_ristretto255_point_t points[11];
      44          63 :   fd_ristretto255_point_t y0[1];
      45          63 :   fd_ristretto255_point_t res[1];
      46             : 
      47          63 :   if( FD_UNLIKELY( fd_curve25519_scalar_validate( proof->zs )==NULL ) ) {
      48           0 :     return FD_ZKSDK_VERIFY_PROOF_ERROR;
      49           0 :   }
      50          63 :   if( FD_UNLIKELY( fd_curve25519_scalar_validate( proof->zx )==NULL ) ) {
      51           0 :     return FD_ZKSDK_VERIFY_PROOF_ERROR;
      52           0 :   }
      53          63 :   if( FD_UNLIKELY( fd_curve25519_scalar_validate( proof->zr )==NULL ) ) {
      54           0 :     return FD_ZKSDK_VERIFY_PROOF_ERROR;
      55           0 :   }
      56             : 
      57          63 :   fd_ristretto255_point_set( &points[0], fd_zksdk_basepoint_G );
      58          63 :   fd_ristretto255_point_set( &points[1], fd_zksdk_basepoint_H );
      59          63 :   if( FD_UNLIKELY( fd_ristretto255_point_decompress( y0, proof->y0 )==NULL ) ) {
      60           0 :     return FD_ZKSDK_VERIFY_PROOF_ERROR;
      61           0 :   }
      62          63 :   if( FD_UNLIKELY( fd_ristretto255_point_decompress( &points[2], pubkey1 )==NULL ) ) {
      63           9 :     return FD_ZKSDK_VERIFY_PROOF_ERROR;
      64           9 :   }
      65          54 :   if( FD_UNLIKELY( fd_ristretto255_point_decompress( &points[3], &ciphertext1[32] )==NULL ) ) {
      66           0 :     return FD_ZKSDK_VERIFY_PROOF_ERROR;
      67           0 :   }
      68          54 :   if( FD_UNLIKELY( fd_ristretto255_point_decompress( &points[4], proof->y1 )==NULL ) ) {
      69           0 :     return FD_ZKSDK_VERIFY_PROOF_ERROR;
      70           0 :   }
      71          54 :   if( FD_UNLIKELY( fd_ristretto255_point_decompress( &points[5], ciphertext1 )==NULL ) ) {
      72           0 :     return FD_ZKSDK_VERIFY_PROOF_ERROR;
      73           0 :   }
      74          54 :   if( FD_UNLIKELY( fd_ristretto255_point_decompress( &points[6], proof->y2 )==NULL ) ) {
      75           0 :     return FD_ZKSDK_VERIFY_PROOF_ERROR;
      76           0 :   }
      77          54 :   if( FD_UNLIKELY( fd_ristretto255_point_decompress( &points[7], ciphertext2 )==NULL ) ) {
      78           0 :     return FD_ZKSDK_VERIFY_PROOF_ERROR;
      79           0 :   }
      80          54 :   if( FD_UNLIKELY( fd_ristretto255_point_decompress( &points[8], proof->y3 )==NULL ) ) {
      81           0 :     return FD_ZKSDK_VERIFY_PROOF_ERROR;
      82           0 :   }
      83          54 :   if( FD_UNLIKELY( fd_ristretto255_point_decompress( &points[9], &ciphertext2[32] )==NULL ) ) {
      84           0 :     return FD_ZKSDK_VERIFY_PROOF_ERROR;
      85           0 :   }
      86          54 :   if( FD_UNLIKELY( fd_ristretto255_point_decompress( &points[10], pubkey2 )==NULL ) ) {
      87           0 :     return FD_ZKSDK_VERIFY_PROOF_ERROR;
      88           0 :   }
      89             : 
      90             :   /* Finalize transcript and extract challenges */
      91          54 :   fd_zksdk_transcript_domsep_ciph_ciph_eq_proof( transcript );
      92          54 :   int val = FD_TRANSCRIPT_SUCCESS;
      93          54 :   val |= fd_zksdk_transcript_validate_and_append_point( transcript, FD_TRANSCRIPT_LITERAL("Y_0"), proof->y0);
      94          54 :   val |= fd_zksdk_transcript_validate_and_append_point( transcript, FD_TRANSCRIPT_LITERAL("Y_1"), proof->y1);
      95          54 :   val |= fd_zksdk_transcript_validate_and_append_point( transcript, FD_TRANSCRIPT_LITERAL("Y_2"), proof->y2);
      96          54 :   val |= fd_zksdk_transcript_validate_and_append_point( transcript, FD_TRANSCRIPT_LITERAL("Y_3"), proof->y3);
      97          54 :   if( FD_UNLIKELY( val != FD_TRANSCRIPT_SUCCESS ) ) {
      98           0 :     return FD_ZKSDK_VERIFY_PROOF_ERROR;
      99           0 :   }
     100             : 
     101          54 :   uchar c[ 32 ];
     102          54 :   uchar w[ 32 ];
     103          54 :   fd_zksdk_transcript_challenge_scalar( c, transcript, FD_TRANSCRIPT_LITERAL("c") );
     104          54 :   fd_zksdk_transcript_challenge_scalar( w, transcript, FD_TRANSCRIPT_LITERAL("w") );
     105             : 
     106          54 :   uchar ww[ 32 ];
     107          54 :   fd_curve25519_scalar_mul( ww, w, w );
     108             : 
     109             :   /* Compute scalars */
     110          54 :   fd_curve25519_scalar_add( &scalars[  0*32 ], w, ww );                //  z_x (w + ww)
     111          54 :   fd_curve25519_scalar_mul( &scalars[  0*32 ], &scalars[ 0*32 ], proof->zx );
     112          54 :   fd_curve25519_scalar_mul( &scalars[  1*32 ], proof->zr, ww );        // -c + z_r ww
     113          54 :   fd_curve25519_scalar_sub( &scalars[  1*32 ], &scalars[ 1*32 ], c );
     114          54 :   fd_curve25519_scalar_set( &scalars[  2*32 ], proof->zs );            //  z_s
     115          54 :   fd_curve25519_scalar_mul( &scalars[  3*32 ], &scalars[ 2*32 ], w );  //  z_s w
     116          54 :   fd_curve25519_scalar_neg( &scalars[  4*32 ], w );                    // -w
     117          54 :   fd_curve25519_scalar_mul( &scalars[  5*32 ], &scalars[ 4*32 ], c );  // -w c
     118          54 :   fd_curve25519_scalar_neg( &scalars[  6*32 ], ww );                   // -ww
     119          54 :   fd_curve25519_scalar_mul( &scalars[  7*32 ], &scalars[ 6*32 ], c );  // -ww c
     120          54 :   fd_curve25519_scalar_mul( ww, ww, w );
     121          54 :   fd_curve25519_scalar_neg( &scalars[  8*32 ], ww );                   // -www
     122          54 :   fd_curve25519_scalar_mul( &scalars[  9*32 ], &scalars[ 8*32 ], c );  // -www c
     123          54 :   fd_curve25519_scalar_mul( &scalars[ 10*32 ], proof->zr, ww );        //  www z_r
     124             :   
     125             :   /* Compute the final MSM */
     126          54 :   fd_ristretto255_multi_scalar_mul( res, scalars, points, 11 );
     127             : 
     128          54 :   if( FD_LIKELY( fd_ristretto255_point_eq( res, y0 ) ) ) {
     129          45 :     return FD_EXECUTOR_INSTR_SUCCESS;
     130          45 :   }
     131           9 :   return FD_ZKSDK_VERIFY_PROOF_ERROR;
     132          54 : }
     133             : 
     134             : /* https://github.com/anza-xyz/agave/blob/v2.0.1/zk-sdk/src/zk_elgamal_proof_program/proof_data/ciphertext_ciphertext_equality.rs#L105 */
     135             : int
     136          63 : fd_zksdk_instr_verify_proof_ciphertext_ciphertext_equality( void const * _context, void const * _proof ) {
     137          63 :   fd_zksdk_transcript_t transcript[1];
     138          63 :   fd_zksdk_ciph_ciph_eq_context_t const * context = _context;
     139          63 :   fd_zksdk_ciph_ciph_eq_proof_t const *   proof   = _proof;
     140             : 
     141          63 :   ciphertext_ciphertext_equality_transcript_init( transcript, context );
     142          63 :   return fd_zksdk_verify_proof_ciphertext_ciphertext_equality(
     143          63 :     proof,
     144          63 :     context->pubkey1,
     145          63 :     context->pubkey2,
     146          63 :     context->ciphertext1,
     147          63 :     context->ciphertext2,
     148          63 :     transcript
     149          63 :   );
     150          63 : }

Generated by: LCOV version 1.14