LCOV - code coverage report
Current view: top level - ballet/bn254 - fd_bn254_scalar.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 18 18 100.0 %
Date: 2024-11-13 11:58:15 Functions: 5 25 20.0 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_ballet_bn254_fd_bn254_scalar_h
       2             : #define HEADER_fd_src_ballet_bn254_fd_bn254_scalar_h
       3             : 
       4             : /* Implementation of the BN254 scalar field, based on fiat-crypto.
       5             : 
       6             :    This covers 2 main use cases:
       7             :    - scalar validation, used e.g. in BN254 point scalar mul
       8             :    - scalar arithmetic, used e.g. to compute Poseidon hash
       9             : 
      10             :    The primary consumer is Firedancer VM (Solana syscalls).
      11             :    Therefore, input is little endian and already aligned. */
      12             : 
      13             : #include "../fd_ballet_base.h"
      14             : #include "../bigint/fd_uint256.h"
      15             : #include "../fiat-crypto/bn254_scalar_64.c"
      16             : 
      17             : /* The implementation is based on fiat-crypto.
      18             :    Unfortunately mul is dramatically slow on gcc, so we reimplemented
      19             :    it in ballet/bigint/uint256_mul.h, based on uint128.
      20             :    When uint128 is not available we fall back on fiat-crypto. */
      21             : #define USE_FIAT_CRYPTO_MUL !FD_HAS_INT128
      22             : 
      23             : /* fd_bn254_scalar represents a scalar as a buffer of 32 bytes,
      24             :    or equivalently (on little endian platforms) an array of 4 ulong. */
      25             : typedef fd_uint256_t fd_bn254_scalar_t;
      26             : 
      27             : /* const r, used to validate a scalar field element.
      28             :    NOT Montgomery.
      29             :    0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001 */
      30             : static const fd_bn254_scalar_t fd_bn254_const_r[1] = {{{
      31             :   0x43e1f593f0000001, 0x2833e84879b97091, 0xb85045b68181585d, 0x30644e72e131a029,
      32             : }}};
      33             : 
      34             : /* const 1/r for CIOS mul */
      35             : static const ulong fd_bn254_const_r_inv = 0xC2E1F593EFFFFFFFUL;
      36             : 
      37             : FD_PROTOTYPES_BEGIN
      38             : 
      39             : /* fd_bn254_scalar_validate validates that the input scalar s
      40             :    is between 0 and r-1, included.
      41             :    This function works on 32-byte input buffer with no memory
      42             :    copies (assuming both platform and input are little endian). */
      43             : static inline int
      44         294 : fd_bn254_scalar_validate( fd_bn254_scalar_t const * s ) {
      45         294 :   return fd_uint256_cmp( s, fd_bn254_const_r ) < 0;
      46         294 : }
      47             : 
      48             : static inline fd_bn254_scalar_t *
      49             : fd_bn254_scalar_from_mont( fd_bn254_scalar_t *       r,
      50          63 :                            fd_bn254_scalar_t const * a ) {
      51          63 :   fiat_bn254_scalar_from_montgomery( r->limbs, a->limbs );
      52          63 :   return r;
      53          63 : }
      54             : 
      55             : static inline fd_bn254_scalar_t *
      56             : fd_bn254_scalar_to_mont( fd_bn254_scalar_t *       r,
      57         288 :                          fd_bn254_scalar_t const * a ) {
      58         288 :   fiat_bn254_scalar_to_montgomery( r->limbs, a->limbs );
      59         288 :   return r;
      60         288 : }
      61             : 
      62             : static inline fd_bn254_scalar_t *
      63             : fd_bn254_scalar_add( fd_bn254_scalar_t *       r,
      64             :                      fd_bn254_scalar_t const * a,
      65      208716 :                      fd_bn254_scalar_t const * b ) {
      66      208716 :   fiat_bn254_scalar_add( r->limbs, a->limbs, b->limbs );
      67      208716 :   return r;
      68      208716 : }
      69             : 
      70             : #if USE_FIAT_CRYPTO_MUL
      71             : 
      72             : static inline fd_bn254_scalar_t *
      73             : fd_bn254_scalar_mul( fd_bn254_scalar_t *       r,
      74             :                      fd_bn254_scalar_t const * a,
      75             :                      fd_bn254_scalar_t const * b ) {
      76             :   fiat_bn254_scalar_mul( r->limbs, a->limbs, b->limbs );
      77             :   return r;
      78             : }
      79             : 
      80             : static inline fd_bn254_scalar_t *
      81             : fd_bn254_scalar_sqr( fd_bn254_scalar_t *       r,
      82             :                      fd_bn254_scalar_t const * a ) {
      83             :   fiat_bn254_scalar_square( r->limbs, a->limbs );
      84             :   return r;
      85             : }
      86             : 
      87             : #else
      88             : 
      89             : FD_UINT256_FP_MUL_IMPL(fd_bn254_scalar, fd_bn254_const_r, fd_bn254_const_r_inv)
      90             : 
      91             : static inline fd_bn254_scalar_t *
      92             : fd_bn254_scalar_sqr( fd_bn254_scalar_t *       r,
      93       12846 :                      fd_bn254_scalar_t const * a ) {
      94       12846 :   return fd_bn254_scalar_mul( r, a, a );
      95       12846 : }
      96             : 
      97             : #endif
      98             : 
      99             : FD_PROTOTYPES_END
     100             : 
     101             : #endif /* HEADER_fd_src_ballet_bn254_fd_bn254_scalar_h */

Generated by: LCOV version 1.14