LCOV - code coverage report
Current view: top level - ballet/bn254 - fd_poseidon.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 1 0.0 %
Date: 2026-10-22 18:10:43 Functions: 0 0 -

          Line data    Source code
       1             : #ifndef HEADER_fd_src_ballet_bn254_fd_poseidon_h
       2             : #define HEADER_fd_src_ballet_bn254_fd_poseidon_h
       3             : 
       4             : /* Implementation of the Poseidon hash function over BN254 scalar field.
       5             :    Based on Rust light-poseidon v0.2.0:
       6             :    https://github.com/Lightprotocol/light-poseidon/blob/v0.2.0/light-poseidon/src/lib.rs#L377
       7             :    That is in turn based on Circom v2.0.x:
       8             :    https://github.com/iden3/circomlib/blob/v2.0.5/circuits/poseidon.circom */
       9             : 
      10             : #include "../fd_ballet_base.h"
      11             : #include "./fd_bn254_scalar.h"
      12             : 
      13           0 : #define FD_POSEIDON_HASH_SZ   (32UL)
      14             : #define FD_POSEIDON_MAX_WIDTH (12UL)
      15             : 
      16             : /* Hash result. Actually a value in the bn254 field */
      17             : struct fd_poseidon_hash_result {
      18             :   uchar v[ FD_POSEIDON_HASH_SZ ];
      19             : };
      20             : typedef struct fd_poseidon_hash_result fd_poseidon_hash_result_t;
      21             : 
      22             : struct FD_ALIGNED fd_poseidon {
      23             :   fd_bn254_scalar_t state[ 1+FD_POSEIDON_MAX_WIDTH ];
      24             :   ulong             cnt;        /* How many elements have been appended total */
      25             :   int               big_endian; /* 0 little endian, 1 big endian */
      26             : };
      27             : typedef struct fd_poseidon fd_poseidon_t;
      28             : 
      29             : struct fd_poseidon_par {
      30             :   fd_bn254_scalar_t const * ark;
      31             :   fd_bn254_scalar_t const * mds;
      32             :   fd_bn254_scalar_t const * ark_start;
      33             :   fd_bn254_scalar_t const * ark_partial;
      34             :   fd_bn254_scalar_t const * ark_end;
      35             :   fd_bn254_scalar_t const * pre_sparse_mds;
      36             :   fd_bn254_scalar_t const * sparse_mds_row;
      37             :   fd_bn254_scalar_t const * sparse_mds_col;
      38             : };
      39             : typedef struct fd_poseidon_par fd_poseidon_par_t;
      40             : 
      41             : FD_PROTOTYPES_BEGIN
      42             : 
      43             : /* fd_poseidon_init starts a Poseidon calculation.
      44             :    pos is assumed to be a current local join to a Poseidon calculation
      45             :    state with no other concurrent operation that would modify the state
      46             :    while this is executing.  Any preexisting state for an in-progress or
      47             :    recently completed calculation will be discarded.
      48             :    if big_endian>0 treats all inputs (append) and output (fini) as big endian,
      49             :    otherwise treats them all as little endian.
      50             :    Returns pos (on return, pos will have the state of a new in-progress
      51             :    calculation). */
      52             : 
      53             : fd_poseidon_t *
      54             : fd_poseidon_init( fd_poseidon_t * pos,
      55             :                   int const       big_endian );
      56             : 
      57             : /* fd_poseidon_append adds sz bytes locally pointed to by data an
      58             :    in-progress Poseidon calculation.
      59             :    out is assumed to be valid (i.e. is a current local join to a Poseidon
      60             :    calculation state with no other concurrent operations that would modify
      61             :    the state while this is executing). out==NULL is ok to allow chaining:
      62             :      fd_poseidon_append( fd_poseidon_append( ... ) )
      63             :    data points to the first of the sz bytes, and will be unmodified while
      64             :    this is running with no interest retained after return.
      65             :    data represents a bn254 scalar, i.e. a 256-bit bigint modulo a prime,
      66             :    and must be exactly 32 bytes long.
      67             :    Returns out on success, NULL in case of error:
      68             :    - if pos==NULL
      69             :    - if sz!=32
      70             :    - if data >= modulus
      71             :    - if fd_poseidon_append is called more than 12 times on the same pos
      72             : 
      73             :    Note: unlike other hash functions, each call to fd_poseidon_append
      74             :    attempts to append a new scalar to the current state.
      75             :    This implementation is modeled around Rust light-poseidon, that in
      76             :    turn is modeled around Circom implementation.
      77             :    It supports hashing a max of FD_POSEIDON_MAX_WIDTH elements. */
      78             : 
      79             : fd_poseidon_t *
      80             : fd_poseidon_append( fd_poseidon_t * pos,
      81             :                     uchar const *   data,
      82             :                     ulong           sz );
      83             : 
      84             : /* fd_poseidon_fini finishes a Poseidon calculation.
      85             :    out is assumed to be valid (i.e. is a current local join to a Poseidon
      86             :    calculation state with no other concurrent operations that would modify
      87             :    the state while this is executing). out==NULL is ok to allow chaining:
      88             :      fd_poseidon_fini( fd_poseidon_append( ... ) )
      89             :    hash points to the first byte of a 32-byte memory region where the
      90             :    result of the calculation should be stored.
      91             :    Returns hash, or NULL if pos==NULL (on return, there will be no calculation
      92             :    in-progress on pos and 32-byte buffer pointed to by hash will be populated
      93             :    with the calculation result). */
      94             : 
      95             : uchar *
      96             : fd_poseidon_fini( fd_poseidon_t * pos,
      97             :                   uchar           hash[ FD_POSEIDON_HASH_SZ ] );
      98             : 
      99             : FD_PROTOTYPES_END
     100             : 
     101             : #endif /* HEADER_fd_src_ballet_bn254_fd_poseidon_h */

Generated by: LCOV version 1.14