github.com/onflow/flow-go/crypto@v0.24.8/dkg_core.c (about)

     1  // +build relic
     2  
     3  #include "dkg_include.h"
     4  
     5  
     6  #define N_max 250
     7  #define N_bits_max 8  // log(250)  
     8  #define T_max  ((N_max-1)/2)
     9  
    10  // computes P(x) = a_0 + a_1*x + .. + a_n x^n (mod r)
    11  // r being the order of G1
    12  // writes P(x) in out and P(x).g2 in y if y is non NULL
    13  // x being a small integer
    14  void Zr_polynomialImage_export(byte* out, ep2_t y, const bn_st* a, const int a_size, const byte x){
    15      bn_t image;
    16      bn_new(image);
    17      Zr_polynomialImage(image, y, a, a_size, x);
    18      // exports the result
    19      const int out_size = Fr_BYTES;
    20      bn_write_bin(out, out_size, image);
    21      bn_free(image);
    22  }
    23  
    24  // computes P(x) = a_0 + a_1*x + .. + a_n x^n (mod r)
    25  // r being the order of G1
    26  // writes P(x) in out and P(x).g2 in y if y is non NULL
    27  // x being a small integer
    28  void Zr_polynomialImage(bn_t image, ep2_t y, const bn_st *a, const int a_size, const byte x){
    29      bn_t r;
    30      bn_new(r); 
    31      g2_get_ord(r);
    32      
    33      // temp variables
    34      bn_t acc;
    35      bn_new(acc); 
    36      bn_new_size(acc, BITS_TO_DIGITS(Fr_BITS+8+1));
    37      bn_set_dig(acc, 0);
    38  
    39      for (int i=a_size-1; i >= 0; i--) {
    40          bn_mul_dig(acc, acc, x);
    41          // Use basic reduction as it's an 9-bits reduction 
    42          // in the worst case (|acc|<|r|+9 )
    43          bn_mod_basic(acc, acc, r);
    44          bn_add(acc, acc, &a[i]);
    45      }
    46      // export the result
    47      bn_mod_basic(image, acc, r);
    48  
    49      // compute y = P(x).g2
    50      if (y) g2_mul_gen(y, acc);
    51  
    52      bn_free(acc)
    53      bn_free(r);
    54  }
    55  
    56  // computes Q(x) = A_0 + A_1*x + ... +  A_n*x^n  in G2
    57  // and stores the point in y
    58  // r is the order of G2
    59  static void G2_polynomialImage(ep2_t y, const ep2_st* A, const int len_A,
    60           const byte x, const bn_t r){
    61      
    62      bn_t bn_x;        
    63      bn_new(bn_x);    
    64      ep2_set_infty(y);
    65      bn_set_dig(bn_x, x);
    66      for (int i = len_A-1; i >= 0 ; i--) {
    67          ep2_mul_lwnaf(y, y, bn_x);
    68          ep2_add_projc(y, y, (ep2_st*)&A[i]);
    69      }
    70  
    71      ep2_norm(y, y); // not necessary but left here to optimize the 
    72                      // multiple pairing computations with the same public key
    73      bn_free(bn_x);
    74  }
    75  
    76  // compute the participants public keys from the verification vector
    77  // y[i] = Q(i+1) for all participants i, with:
    78  // Q(x) = A_0 + A_1*x + ... +  A_n*x^n  in G2
    79  void G2_polynomialImages(ep2_st *y, const int len_y, const ep2_st* A, const int len_A) {
    80      // order r
    81      bn_t r;
    82      bn_new(r); 
    83      g2_get_ord(r);
    84      for (byte i=0; i<len_y; i++) {
    85          //y[i] = Q(i+1)
    86          G2_polynomialImage(y+i , A, len_A, i+1, r);
    87      }
    88      bn_free(r);
    89  }
    90  
    91  // export an array of ep2_st into an array of bytes
    92  // the length matching is supposed to be checked
    93  void ep2_vector_write_bin(byte* out, const ep2_st* A, const int len) {
    94      const int size = (G2_BYTES/(G2_SERIALIZATION+1));
    95      byte* p = out;
    96      for (int i=0; i<len; i++){
    97          ep2_write_bin_compact(p, &A[i], size);
    98          p += size;
    99      }
   100  }
   101  
   102  // The function imports an array of ep2_st from an array of bytes
   103  // the length matching is supposed to be already done.
   104  //
   105  // It returns RLC_OK if reading all the vector succeeded and RLC_ERR 
   106  // otherwise.
   107  int ep2_vector_read_bin(ep2_st* A, const byte* src, const int len){
   108      const int size = (G2_BYTES/(G2_SERIALIZATION+1));
   109      byte* p = (byte*) src;
   110      for (int i=0; i<len; i++){
   111          int read_ret = ep2_read_bin_compact(&A[i], p, size); // returns RLC_OK or RLC_ERR
   112          if (read_ret != RLC_OK)
   113              return read_ret;
   114          p += size;
   115      }
   116      return RLC_OK;
   117  }
   118  
   119  // returns 1 if g2^x = y, where g2 is the generator of G2
   120  // returns 0 otherwise
   121  int verifyshare(const bn_t x, const ep2_t y) {
   122      ep2_t res;
   123      ep2_new(res);
   124      g2_mul_gen(res, (bn_st*)x);
   125      return (ep2_cmp(res, (ep2_st*)y) == RLC_EQ);
   126  }
   127