LCOV - code coverage report
Current view: top level - ballet/bn254 - fd_bn254_final_exp.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 114 114 100.0 %
Date: 2026-08-08 04:48:28 Functions: 3 3 100.0 %

          Line data    Source code
       1             : #include "./fd_bn254_field_inl.h"
       2             : 
       3             : /* Pairing final exponentiation */
       4             : 
       5             : static fd_bn254_fp12_t *
       6             : fd_bn254_fp12_sqr_fast( fd_bn254_fp12_t * r,
       7      130977 :                         fd_bn254_fp12_t const * a ) {
       8             :   /* Cyclotomic sqr, https://eprint.iacr.org/2009/565, Sec. 3.2.
       9             :      Variant of https://eprint.iacr.org/2010/354, Alg. 24.
      10             :      This works when a^(p^6+1)=1, e.g. during pairing final exp. */
      11      130977 :   fd_bn254_fp2_t t[9];
      12             : 
      13      130977 :   fd_bn254_fp2_sqr( &t[0], &a->el[1].el[1] );
      14      130977 :   fd_bn254_fp2_sqr( &t[1], &a->el[0].el[0] );
      15      130977 :   fd_bn254_fp2_add( &t[6], &a->el[1].el[1], &a->el[0].el[0] );
      16      130977 :   fd_bn254_fp2_sqr( &t[6], &t[6] );
      17      130977 :   fd_bn254_fp2_sub( &t[6], &t[6], &t[0] );
      18      130977 :   fd_bn254_fp2_sub( &t[6], &t[6], &t[1] );
      19             : 
      20      130977 :   fd_bn254_fp2_sqr( &t[2], &a->el[0].el[2] );
      21      130977 :   fd_bn254_fp2_sqr( &t[3], &a->el[1].el[0] );
      22      130977 :   fd_bn254_fp2_add( &t[7], &a->el[0].el[2], &a->el[1].el[0] );
      23      130977 :   fd_bn254_fp2_sqr( &t[7], &t[7] );
      24      130977 :   fd_bn254_fp2_sub( &t[7], &t[7], &t[2] );
      25      130977 :   fd_bn254_fp2_sub( &t[7], &t[7], &t[3] );
      26             : 
      27      130977 :   fd_bn254_fp2_sqr( &t[4], &a->el[1].el[2] );
      28      130977 :   fd_bn254_fp2_sqr( &t[5], &a->el[0].el[1] );
      29      130977 :   fd_bn254_fp2_add( &t[8], &a->el[1].el[2], &a->el[0].el[1] );
      30      130977 :   fd_bn254_fp2_sqr( &t[8], &t[8] );
      31      130977 :   fd_bn254_fp2_sub( &t[8], &t[8], &t[4] );
      32      130977 :   fd_bn254_fp2_sub( &t[8], &t[8], &t[5] );
      33      130977 :   fd_bn254_fp2_mul_by_xi( &t[8], &t[8] );
      34             : 
      35      130977 :   fd_bn254_fp2_mul_by_xi( &t[0], &t[0] );
      36      130977 :   fd_bn254_fp2_add( &t[0], &t[0], &t[1] );
      37      130977 :   fd_bn254_fp2_mul_by_xi( &t[2], &t[2] );
      38      130977 :   fd_bn254_fp2_add( &t[2], &t[2], &t[3] );
      39      130977 :   fd_bn254_fp2_mul_by_xi( &t[4], &t[4] );
      40      130977 :   fd_bn254_fp2_add( &t[4], &t[4], &t[5] );
      41             : 
      42      130977 :   fd_bn254_fp2_sub( &r->el[0].el[0], &t[0], &a->el[0].el[0] );
      43      130977 :   fd_bn254_fp2_add( &r->el[0].el[0], &r->el[0].el[0], &r->el[0].el[0] );
      44      130977 :   fd_bn254_fp2_add( &r->el[0].el[0], &r->el[0].el[0], &t[0] );
      45      130977 :   fd_bn254_fp2_sub( &r->el[0].el[1], &t[2], &a->el[0].el[1] );
      46      130977 :   fd_bn254_fp2_add( &r->el[0].el[1], &r->el[0].el[1], &r->el[0].el[1] );
      47      130977 :   fd_bn254_fp2_add( &r->el[0].el[1], &r->el[0].el[1], &t[2] );
      48      130977 :   fd_bn254_fp2_sub( &r->el[0].el[2], &t[4], &a->el[0].el[2] );
      49      130977 :   fd_bn254_fp2_add( &r->el[0].el[2], &r->el[0].el[2], &r->el[0].el[2] );
      50      130977 :   fd_bn254_fp2_add( &r->el[0].el[2], &r->el[0].el[2], &t[4] );
      51             : 
      52      130977 :   fd_bn254_fp2_add( &r->el[1].el[0], &t[8], &a->el[1].el[0] );
      53      130977 :   fd_bn254_fp2_add( &r->el[1].el[0], &r->el[1].el[0], &r->el[1].el[0] );
      54      130977 :   fd_bn254_fp2_add( &r->el[1].el[0], &r->el[1].el[0], &t[8] );
      55      130977 :   fd_bn254_fp2_add( &r->el[1].el[1], &t[6], &a->el[1].el[1] );
      56      130977 :   fd_bn254_fp2_add( &r->el[1].el[1], &r->el[1].el[1], &r->el[1].el[1] );
      57      130977 :   fd_bn254_fp2_add( &r->el[1].el[1], &r->el[1].el[1], &t[6] );
      58      130977 :   fd_bn254_fp2_add( &r->el[1].el[2], &t[7], &a->el[1].el[2] );
      59      130977 :   fd_bn254_fp2_add( &r->el[1].el[2], &r->el[1].el[2], &r->el[1].el[2] );
      60      130977 :   fd_bn254_fp2_add( &r->el[1].el[2], &r->el[1].el[2], &t[7] );
      61      130977 :   return r;
      62      130977 : }
      63             : 
      64             : fd_bn254_fp12_t *
      65             : fd_bn254_fp12_pow_x( fd_bn254_fp12_t * restrict r,
      66        2079 :                      fd_bn254_fp12_t const *    a ) {
      67             :   /* https://github.com/Consensys/gnark-crypto/blob/v0.12.1/ecc/bn254/internal/fptower/e12_pairing.go#L16 */
      68        2079 :   fd_bn254_fp12_t t[7];
      69        2079 :   fd_bn254_fp12_sqr_fast( &t[3], a );
      70        2079 :   fd_bn254_fp12_sqr_fast( &t[5], &t[3] );
      71        2079 :   fd_bn254_fp12_sqr_fast( r,     &t[5] );
      72        2079 :   fd_bn254_fp12_sqr_fast( &t[0], r );
      73        2079 :   fd_bn254_fp12_mul     ( &t[2], &t[0], a );
      74        2079 :   fd_bn254_fp12_mul     ( &t[0], &t[2], &t[3] );
      75        2079 :   fd_bn254_fp12_mul     ( &t[1], &t[0], a );
      76        2079 :   fd_bn254_fp12_mul     ( &t[4], &t[2], r );
      77        2079 :   fd_bn254_fp12_sqr_fast( &t[6], &t[2] );
      78        2079 :   fd_bn254_fp12_mul     ( &t[1], &t[1], &t[0] );
      79        2079 :   fd_bn254_fp12_mul     ( &t[0], &t[1], &t[3] );
      80       14553 :   for( int i=0; i<6; i++ ) fd_bn254_fp12_sqr_fast( &t[6], &t[6] );
      81        2079 :   fd_bn254_fp12_mul     ( &t[5], &t[5], &t[6] );
      82        2079 :   fd_bn254_fp12_mul     ( &t[5], &t[5], &t[4] );
      83       16632 :   for( int i=0; i<7; i++ ) fd_bn254_fp12_sqr_fast( &t[5], &t[5] );
      84        2079 :   fd_bn254_fp12_mul     ( &t[4], &t[4], &t[5] );
      85       18711 :   for( int i=0; i<8; i++ ) fd_bn254_fp12_sqr_fast( &t[4], &t[4] );
      86        2079 :   fd_bn254_fp12_mul     ( &t[4], &t[4], &t[0] );
      87        2079 :   fd_bn254_fp12_mul     ( &t[3], &t[3], &t[4] );
      88       14553 :   for( int i=0; i<6; i++ ) fd_bn254_fp12_sqr_fast( &t[3], &t[3] );
      89        2079 :   fd_bn254_fp12_mul     ( &t[2], &t[2], &t[3] );
      90       18711 :   for( int i=0; i<8; i++ ) fd_bn254_fp12_sqr_fast( &t[2], &t[2] );
      91        2079 :   fd_bn254_fp12_mul     ( &t[2], &t[2], &t[0] );
      92       14553 :   for( int i=0; i<6; i++ ) fd_bn254_fp12_sqr_fast( &t[2], &t[2] );
      93        2079 :   fd_bn254_fp12_mul     ( &t[2], &t[2], &t[0] );
      94       22869 :   for( int i=0; i<10; i++ ) fd_bn254_fp12_sqr_fast( &t[2], &t[2] );
      95        2079 :   fd_bn254_fp12_mul     ( &t[1], &t[1], &t[2] );
      96       14553 :   for( int i=0; i<6; i++ ) fd_bn254_fp12_sqr_fast( &t[1], &t[1] );
      97        2079 :   fd_bn254_fp12_mul     ( &t[0], &t[0], &t[1] );
      98        2079 :   fd_bn254_fp12_mul     ( r, r, &t[0] );
      99        2079 :   return r;
     100        2079 : }
     101             : 
     102             : fd_bn254_fp12_t *
     103             : fd_bn254_final_exp( fd_bn254_fp12_t *       r,
     104         693 :                     fd_bn254_fp12_t * const x ) {
     105             :   /* https://github.com/Consensys/gnark-crypto/blob/v0.12.1/ecc/bn254/pairing.go#L62 */
     106         693 :   fd_bn254_fp12_t t[5], s[1];
     107         693 :   fd_bn254_fp12_conj ( &t[0], x );            /* x^(p^6) */
     108         693 :   fd_bn254_fp12_inv  ( &t[1], x );            /* x^(-1) */
     109         693 :   fd_bn254_fp12_mul  ( &t[0], &t[0], &t[1] ); /* x^(p^6-1) */
     110         693 :   fd_bn254_fp12_frob2( &t[2], &t[0] );        /* x^(p^6-1)(p^2) */
     111         693 :   fd_bn254_fp12_mul  ( s, &t[0], &t[2] );     /* x^(p^6-1)(p^2+1) */
     112             :   /* Fast chain, https://eprint.iacr.org/2015/192, Alg. 10.
     113             :      Variant of https://eprint.iacr.org/2010/354, Alg. 31. */
     114         693 :   fd_bn254_fp12_pow_x   ( &t[0], s );
     115         693 :   fd_bn254_fp12_conj    ( &t[0], &t[0] );
     116         693 :   fd_bn254_fp12_sqr_fast( &t[0], &t[0] );
     117         693 :   fd_bn254_fp12_sqr_fast( &t[1], &t[0] );
     118         693 :   fd_bn254_fp12_mul     ( &t[1], &t[1], &t[0] );
     119             : 
     120         693 :   fd_bn254_fp12_pow_x   ( &t[2], &t[1] );
     121         693 :   fd_bn254_fp12_conj    ( &t[2], &t[2] );
     122         693 :   fd_bn254_fp12_conj    ( &t[3], &t[1] );
     123         693 :   fd_bn254_fp12_mul     ( &t[1], &t[2], &t[3] );
     124             : 
     125         693 :   fd_bn254_fp12_sqr_fast( &t[3], &t[2] );
     126         693 :   fd_bn254_fp12_pow_x   ( &t[4], &t[3] );
     127         693 :   fd_bn254_fp12_mul     ( &t[4], &t[1], &t[4] );
     128         693 :   fd_bn254_fp12_mul     ( &t[3], &t[0], &t[4] );
     129         693 :   fd_bn254_fp12_mul     ( &t[0], &t[2], &t[4] );
     130         693 :   fd_bn254_fp12_mul     ( &t[0], &t[0], s );
     131             : 
     132         693 :   fd_bn254_fp12_frob    ( &t[2], &t[3] );
     133         693 :   fd_bn254_fp12_mul     ( &t[0], &t[0], &t[2] );
     134         693 :   fd_bn254_fp12_frob2   ( &t[2], &t[4] );
     135         693 :   fd_bn254_fp12_mul     ( &t[0], &t[0], &t[2] );
     136             : 
     137         693 :   fd_bn254_fp12_conj    ( &t[2], s );
     138         693 :   fd_bn254_fp12_mul     ( &t[2], &t[2], &t[3] );
     139             :   // fd_bn254_fp12_frob3   ( &t[2], &t[2] );
     140         693 :   fd_bn254_fp12_frob2   ( &t[2], &t[2] );
     141         693 :   fd_bn254_fp12_frob    ( &t[2], &t[2] );
     142         693 :   fd_bn254_fp12_mul     ( r, &t[0], &t[2] );
     143         693 :   return r;
     144         693 : }

Generated by: LCOV version 1.14