LCOV - code coverage report
Current view: top level - flamenco/runtime/program/zksdk/instructions - fd_zksdk_zero_ciphertext.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 53 63 84.1 %
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             : zero_ciphertext_transcript_init( fd_zksdk_transcript_t *                    transcript,
       5         108 :                                  fd_zksdk_zero_ciphertext_context_t const * context ) {
       6         108 :   fd_zksdk_transcript_init( transcript, FD_TRANSCRIPT_LITERAL("zero-ciphertext-instruction") );
       7         108 :   fd_zksdk_transcript_append_pubkey    ( transcript, FD_TRANSCRIPT_LITERAL("pubkey"),     context->pubkey );
       8         108 :   fd_zksdk_transcript_append_ciphertext( transcript, FD_TRANSCRIPT_LITERAL("ciphertext"), context->ciphertext );
       9         108 : }
      10             : 
      11             : /* https://github.com/anza-xyz/agave/blob/v2.0.1/zk-sdk/src/sigma_proofs/zero_ciphertext.rs#L102 */
      12             : static inline int
      13             : fd_zksdk_verify_proof_zero_ciphertext(
      14             :   fd_zksdk_zero_ciphertext_proof_t const * proof,
      15             :   uchar const                              pubkey    [ 32 ],
      16             :   uchar const                              ciphertext[ 64 ],
      17         108 :   fd_zksdk_transcript_t *                  transcript ) {
      18             :   /*
      19             :     We need to verify the 2 following equivalences.
      20             :     Instead of verifying them one by one, it's more efficient to pack
      21             :     them up in a single MSM (and to do so we have to mul by 1, w).
      22             : 
      23             :     (         z P =?= c H + Y_P         ) * 1
      24             :     (         z D =?= c C + Y_D         ) * w
      25             : 
      26             :     We store points and scalars in the following arrays:
      27             : 
      28             :         points  scalars
      29             :     0   H       -c
      30             :     1   P        z
      31             :     2   C       -wc
      32             :     3   D        wz
      33             :     4   Y_D     -w
      34             :     ----------------------- MSM
      35             :         Y_P
      36             :   */
      37             : 
      38             :   /* Validate all inputs */
      39         108 :   uchar scalars[ 5 * 32 ];
      40         108 :   fd_ristretto255_point_t points[5];
      41         108 :   fd_ristretto255_point_t y[1];
      42         108 :   fd_ristretto255_point_t res[1];
      43             : 
      44         108 :   if( FD_UNLIKELY( fd_curve25519_scalar_validate( proof->z )==NULL ) ) {
      45           3 :     return FD_ZKSDK_VERIFY_PROOF_ERROR;
      46           3 :   }
      47             : 
      48         105 :   fd_ristretto255_point_set( &points[0], fd_zksdk_basepoint_H );
      49         105 :   if( FD_UNLIKELY( fd_ristretto255_point_decompress( &points[1], pubkey )==NULL ) ) {
      50           6 :     return FD_ZKSDK_VERIFY_PROOF_ERROR;
      51           6 :   }
      52          99 :   if( FD_UNLIKELY( fd_ristretto255_point_decompress( &points[2], &ciphertext[0] )==NULL ) ) {
      53           0 :     return FD_ZKSDK_VERIFY_PROOF_ERROR;
      54           0 :   }
      55          99 :   if( FD_UNLIKELY( fd_ristretto255_point_decompress( &points[3], &ciphertext[32] )==NULL ) ) {
      56           0 :     return FD_ZKSDK_VERIFY_PROOF_ERROR;
      57           0 :   }
      58          99 :   if( FD_UNLIKELY( fd_ristretto255_point_decompress( &points[4], proof->yd )==NULL ) ) {
      59           0 :     return FD_ZKSDK_VERIFY_PROOF_ERROR;
      60           0 :   }
      61          99 :   if( FD_UNLIKELY( fd_ristretto255_point_decompress( y, proof->yp )==NULL ) ) {
      62           0 :     return FD_ZKSDK_VERIFY_PROOF_ERROR;
      63           0 :   }
      64             : 
      65             :   /* Finalize transcript and extract challenges */
      66          99 :   fd_zksdk_transcript_domsep_zero_ciphertext_proof( transcript );
      67          99 :   int val = FD_TRANSCRIPT_SUCCESS;
      68          99 :   val |= fd_zksdk_transcript_validate_and_append_point( transcript, FD_TRANSCRIPT_LITERAL("Y_P"), proof->yp);
      69          99 :   if( FD_UNLIKELY( val != FD_TRANSCRIPT_SUCCESS ) ) {
      70           0 :     return FD_ZKSDK_VERIFY_PROOF_ERROR;
      71           0 :   }
      72          99 :   fd_zksdk_transcript_append_point( transcript, FD_TRANSCRIPT_LITERAL("Y_D"), proof->yd);
      73             : 
      74          99 :   uchar c[ 32 ];
      75          99 :   uchar w[ 32 ];
      76          99 :   fd_zksdk_transcript_challenge_scalar( c, transcript, FD_TRANSCRIPT_LITERAL("c") );
      77          99 :   fd_zksdk_transcript_challenge_scalar( w, transcript, FD_TRANSCRIPT_LITERAL("w") );
      78             : 
      79             :   /* Compute scalars */
      80          99 :   fd_curve25519_scalar_neg( &scalars[ 0*32 ], c );                   // -c
      81          99 :   fd_curve25519_scalar_set( &scalars[ 1*32 ], proof->z );            //  z
      82          99 :   fd_curve25519_scalar_mul( &scalars[ 2*32 ], &scalars[ 0*32 ], w ); // -wc
      83          99 :   fd_curve25519_scalar_mul( &scalars[ 3*32 ], w, proof->z );         //  wz
      84          99 :   fd_curve25519_scalar_neg( &scalars[ 4*32 ], w );                   // -w
      85             : 
      86             :   /* Compute the final MSM */
      87          99 :   fd_ristretto255_multi_scalar_mul( res, scalars, points, 5 );
      88             : 
      89          99 :   if( FD_LIKELY( fd_ristretto255_point_eq( res, y ) ) ) {
      90          84 :     return FD_EXECUTOR_INSTR_SUCCESS;
      91          84 :   }
      92          15 :   return FD_ZKSDK_VERIFY_PROOF_ERROR;
      93          99 : }
      94             : 
      95             : /* https://github.com/anza-xyz/agave/blob/v2.0.1/zk-sdk/src/zk_elgamal_proof_program/proof_data/zero_ciphertext.rs#L81 */
      96             : int
      97         108 : fd_zksdk_instr_verify_proof_zero_ciphertext( void const * _context, void const * _proof ) {
      98         108 :   fd_zksdk_transcript_t transcript[1];
      99         108 :   fd_zksdk_zero_ciphertext_context_t const * context = _context;
     100         108 :   fd_zksdk_zero_ciphertext_proof_t const *   proof   = _proof;
     101             : 
     102         108 :   zero_ciphertext_transcript_init( transcript, context );
     103         108 :   return fd_zksdk_verify_proof_zero_ciphertext(
     104         108 :     proof,
     105         108 :     context->pubkey,
     106         108 :     context->ciphertext,
     107         108 :     transcript
     108         108 :   );
     109         108 : }

Generated by: LCOV version 1.14