LCOV - code coverage report
Current view: top level - ballet/ed25519 - fd_ristretto255.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 41 41 100.0 %
Date: 2024-11-13 11:58:15 Functions: 10 54 18.5 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_ballet_ed25519_fd_ristretto255_h
       2             : #define HEADER_fd_src_ballet_ed25519_fd_ristretto255_h
       3             : 
       4             : /* fd_ristretto255.h provides the public ristretto255 group element
       5             :    API.
       6             : 
       7             :    This API is specifically only provided for the Solana virtual machine
       8             :    syscall sol_curve_group_op (slow!).  It is guaranteed to be stable
       9             :    irrespective of underlying backend chosen (ref, avx, etc...)
      10             : 
      11             :    All operations in this API should be assumed to take a variable
      12             :    amount of time depending on inputs.  (And thus should not be exposed
      13             :    to secret data) */
      14             : 
      15             : #include "fd_curve25519.h"
      16             : 
      17             : /* fd_ristretto255 provides APIs for the ristretto255 prime order group */
      18             : 
      19             : static const uchar fd_ristretto255_compressed_zero[ 32 ] = {
      20             :   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      21             :   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
      22             : };
      23             : 
      24             : /* fd_ristretto255_point_t is a opaque handle to a ristretto255 group
      25             :    element.  Although it is the same type as an Ed25519 group element,
      26             :    it is unsafe to mix Ed25519 point and ristretto point APIs. */
      27             : 
      28             : typedef fd_ed25519_point_t fd_ristretto255_point_t;
      29             : 
      30           9 : #define fd_ristretto255_point_set_zero   fd_ed25519_point_set_zero
      31         978 : #define fd_ristretto255_point_set        fd_ed25519_point_set
      32     3030348 : #define fd_ristretto255_point_add        fd_ed25519_point_add
      33     3000330 : #define fd_ristretto255_point_sub        fd_ed25519_point_sub
      34     3000000 : #define fd_ristretto255_scalar_validate  fd_ed25519_scalar_validate
      35       30018 : #define fd_ristretto255_scalar_mul       fd_ed25519_scalar_mul
      36        2346 : #define fd_ristretto255_multi_scalar_mul fd_ed25519_multi_scalar_mul
      37      301392 : #define fd_ristretto255_point_decompress fd_ristretto255_point_frombytes
      38      300099 : #define fd_ristretto255_point_compress   fd_ristretto255_point_tobytes
      39             : 
      40             : FD_PROTOTYPES_BEGIN
      41             : 
      42             : uchar *
      43             : fd_ristretto255_point_tobytes( uchar                           buf[ 32 ],
      44             :                                fd_ristretto255_point_t const * p );
      45             : 
      46             : /* fd_ristretto255_point_frombytes decompresses a 32-byte array into
      47             :    an element of the ristretto group h.
      48             :    It returns p on success, NULL on failure. */
      49             : 
      50             : fd_ristretto255_point_t *
      51             : fd_ristretto255_point_frombytes( fd_ristretto255_point_t * p,
      52             :                                   uchar const              buf[ 32 ] );
      53             : 
      54             : /* fd_ristretto255_point_validate checks if a 32-byte array represents
      55             :    a valid element of the ristretto group h.
      56             :    It returns 1 on success, 0 on failure. */
      57             : 
      58             : static inline int
      59           6 : fd_ristretto255_point_validate( uchar const buf[ 32 ] ) {
      60           6 :   fd_ristretto255_point_t t[1];
      61           6 :   return !!fd_ristretto255_point_frombytes( t, buf );
      62           6 : }
      63             : 
      64             : /* fd_ristretto255_point_eq checks if two elements of the ristretto group
      65             :    p and q are equal.
      66             :    It returns 1 on success, 0 on failure. */
      67             : 
      68             : static inline int
      69             : fd_ristretto255_point_eq( fd_ristretto255_point_t * const p,
      70        1041 :                           fd_ristretto255_point_t * const q ) {
      71             :   // https://ristretto.group/details/equality.html
      72        1041 :   fd_f25519_t cmp[2];
      73        1041 :   fd_f25519_t x[2], y[2], _z[2], _t[2];
      74        1041 :   fd_ed25519_point_to( &x[0], &y[0], &_z[0], &_t[0], p );
      75        1041 :   fd_ed25519_point_to( &x[1], &y[1], &_z[1], &_t[1], q );
      76             : 
      77        1041 :   fd_f25519_mul( &cmp[ 0 ], &x[0], &y[1] );
      78        1041 :   fd_f25519_mul( &cmp[ 1 ], &x[1], &y[0] );
      79        1041 :   int xx = fd_f25519_eq( &cmp[ 0 ], &cmp[ 1 ] );
      80             : 
      81        1041 :   fd_f25519_mul( &cmp[ 0 ], &x[0], &x[1] );
      82        1041 :   fd_f25519_mul( &cmp[ 1 ], &y[0], &y[1] );
      83        1041 :   int yy = fd_f25519_eq( &cmp[ 0 ], &cmp[ 1 ] );
      84             : 
      85        1041 :   return xx | yy;
      86        1041 : }
      87             : 
      88             : /* fd_ristretto255_point_eq_neg checks if two elements of the ristretto group
      89             :    p and q are such that -p == q. This uses just 1 extra neg.
      90             :    It returns 1 on success, 0 on failure. */
      91             : 
      92             : static inline int
      93             : fd_ristretto255_point_eq_neg( fd_ristretto255_point_t * const p,
      94         123 :                               fd_ristretto255_point_t * const q ) {
      95             :   // https://ristretto.group/details/equality.html
      96         123 :   fd_f25519_t neg[1];
      97         123 :   fd_f25519_t cmp[2];
      98         123 :   fd_f25519_t x[2], y[2], _z[2], _t[2];
      99         123 :   fd_ed25519_point_to( &x[0], &y[0], &_z[0], &_t[0], p );
     100         123 :   fd_ed25519_point_to( &x[1], &y[1], &_z[1], &_t[1], q );
     101             : 
     102         123 :   fd_f25519_neg( neg, &x[0] );
     103         123 :   fd_f25519_mul( &cmp[ 0 ], neg, &y[1] );
     104         123 :   fd_f25519_mul( &cmp[ 1 ], &x[1], &y[0] );
     105         123 :   int xx = fd_f25519_eq( &cmp[ 0 ], &cmp[ 1 ] );
     106             : 
     107         123 :   fd_f25519_mul( &cmp[ 0 ], neg, &x[1] );
     108         123 :   fd_f25519_mul( &cmp[ 1 ], &y[0], &y[1] );
     109         123 :   int yy = fd_f25519_eq( &cmp[ 0 ], &cmp[ 1 ] );
     110             : 
     111         123 :   return xx | yy;
     112         123 : }
     113             : 
     114             : /* fd_ristretto255_hash_to_curve computes an element h of the ristretto group
     115             :    given an array s of 64-byte of uniformly random input (e.g., the output of a
     116             :    hash function).
     117             :    This function behaves like a random oracle.
     118             :    It returns h. */
     119             : 
     120             : fd_ristretto255_point_t *
     121             : fd_ristretto255_hash_to_curve( fd_ristretto255_point_t * h,
     122             :                                uchar const               s[ 64 ] );
     123             : 
     124             : /* fd_ristretto255_map_to_curve implements the elligato2 map for curve25519,
     125             :    and computes an element h of the ristretto group given an array s of 32-byte 
     126             :    of uniformly random input (e.g., the output of a hash function).
     127             :    This function does NOT behave like a random oracle, and is intended for
     128             :    internal use.
     129             :    It returns h. */
     130             : 
     131             : fd_ristretto255_point_t *
     132             : fd_ristretto255_map_to_curve( fd_ristretto255_point_t * h,
     133             :                               uchar const               s[ 32 ] );
     134             : 
     135             : FD_PROTOTYPES_END
     136             : 
     137             : #endif /* HEADER_fd_src_ballet_ed25519_fd_ristretto255_h */

Generated by: LCOV version 1.14