LCOV - code coverage report
Current view: top level - ballet/bn254 - fd_poseidon.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 9 0.0 %
Date: 2024-11-13 11:58:15 Functions: 0 3 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 * ark;
      31             :   fd_bn254_scalar_t * mds;
      32             : };
      33             : typedef struct fd_poseidon_par fd_poseidon_par_t;
      34             : 
      35             : FD_PROTOTYPES_BEGIN
      36             : 
      37             : /* fd_poseidon_init starts a Poseidon calculation.
      38             :    pos is assumed to be a current local join to a Poseidon calculation
      39             :    state with no other concurrent operation that would modify the state
      40             :    while this is executing.  Any preexisting state for an in-progress or
      41             :    recently completed calculation will be discarded.
      42             :    if big_endian>0 treats all inputs (append) and output (fini) as big endian,
      43             :    otherwise treats them all as little endian.
      44             :    Returns pos (on return, pos will have the state of a new in-progress
      45             :    calculation). */
      46             : 
      47             : fd_poseidon_t *
      48             : fd_poseidon_init( fd_poseidon_t * pos,
      49             :                   int const       big_endian );
      50             : 
      51             : /* fd_poseidon_append adds sz bytes locally pointed to by data an
      52             :    in-progress Poseidon calculation.
      53             :    out is assumed to be valid (i.e. is a current local join to a Poseidon
      54             :    calculation state with no other concurrent operations that would modify
      55             :    the state while this is executing). out==NULL is ok to allow chaining:
      56             :      fd_poseidon_append( fd_poseidon_append( ... ) )
      57             :    data points to the first of the sz bytes, and will be unmodified while
      58             :    this is running with no interest retained after return (data==NULL is fine if sz==0).
      59             :    data represents a bn254 scalar, i.e. a 256-bit bigint modulo a prime.
      60             :    If data is not exactly 32-byte long (sz!=32), then data is padded with 0s
      61             :    during conversion.
      62             :    Returns out on success, NULL in case of error:
      63             :    - if pos==NULL
      64             :    - if data >= modulus (including sz > 32)
      65             :    - if fd_poseidon_append is called more than 12 times on the same pos
      66             : 
      67             :    Note: unlike other hash functions, each call to fd_poseidon_append
      68             :    attempts to append a new scalar to the current state.
      69             :    This implementation is modeled around Rust light-poseidon, that in
      70             :    turn is modeled around Circom implementation.
      71             :    It supports hashing a max of FD_POSEIDON_MAX_WIDTH elements. */
      72             : 
      73             : fd_poseidon_t *
      74             : fd_poseidon_append( fd_poseidon_t * pos,
      75             :                     uchar const *   data,
      76             :                     ulong           sz );
      77             : 
      78             : /* fd_poseidon_fini finishes a Poseidon calculation.
      79             :    out is assumed to be valid (i.e. is a current local join to a Poseidon
      80             :    calculation state with no other concurrent operations that would modify
      81             :    the state while this is executing). out==NULL is ok to allow chaining:
      82             :      fd_poseidon_fini( fd_poseidon_append( ... ) )
      83             :    hash points to the first byte of a 32-byte memory region where the
      84             :    result of the calculation should be stored.
      85             :    Returns hash, or NULL if pos==NULL (on return, there will be no calculation
      86             :    in-progress on pos and 32-byte buffer pointed to by hash will be populated
      87             :    with the calculation result). */
      88             : 
      89             : uchar *
      90             : fd_poseidon_fini( fd_poseidon_t * pos,
      91             :                   uchar           hash[ FD_POSEIDON_HASH_SZ ] );
      92             : 
      93             : /* Hash a series of bytes. */
      94             : static inline int
      95             : fd_poseidon_hash( fd_poseidon_hash_result_t * result,
      96             :                   uchar const *               bytes,
      97             :                   ulong                       bytes_len,
      98           0 :                   int const                   big_endian ) {
      99           0 :   fd_poseidon_t pos[1];
     100           0 :   fd_poseidon_init( pos, big_endian );
     101           0 :   for( ulong i=0; i<bytes_len/32; i++ ) {
     102           0 :     fd_poseidon_append( pos, &bytes[i*32], 32 );
     103           0 :   }
     104           0 :   return !fd_poseidon_fini( pos, fd_type_pun(result) );
     105           0 : }
     106             : 
     107             : FD_PROTOTYPES_END
     108             : 
     109             : #endif /* HEADER_fd_src_ballet_bn254_fd_poseidon_h */

Generated by: LCOV version 1.14