2  *****************************************************************************
 
    4  Fast batch verification signature for ADSNARK.
 
    6  *****************************************************************************
 
    7  * @author     This file is part of libsnark, developed by SCIPR Lab
 
    8  *             and contributors (see AUTHORS).
 
    9  * @copyright  MIT license (see LICENSE file)
 
   10  *****************************************************************************/
 
   13  *****************************************************************************
 
   14  * @author     This file was deed to libsnark by Manuel Barbosa.
 
   15  * @copyright  MIT license (see LICENSE file)
 
   16  *****************************************************************************/
 
   18 #include "depends/libsnark-supercop/include/crypto_sign.h"
 
   20 #include <libsnark/common/default_types/r1cs_ppzkadsnark_pp.hpp>
 
   26 kpT<default_r1cs_ppzkadsnark_pp> sigGen<default_r1cs_ppzkadsnark_pp>(void)
 
   28     kpT<default_r1cs_ppzkadsnark_pp> keys;
 
   29     crypto_sign_ed25519_amd64_51_30k_keypair(
 
   30         keys.vk.vk_bytes, keys.sk.sk_bytes);
 
   35 ed25519_sigT sigSign<default_r1cs_ppzkadsnark_pp>(
 
   36     const ed25519_skT &sk,
 
   38     const libff::G2<snark_pp<default_r1cs_ppzkadsnark_pp>> &Lambda)
 
   41     unsigned long long sigmalen;
 
   42     unsigned char signature[64 + 16 + 320];
 
   43     unsigned char message[16 + 320];
 
   45     libff::G2<snark_pp<default_r1cs_ppzkadsnark_pp>> Lambda_copy(Lambda);
 
   46     Lambda_copy.to_affine_coordinates();
 
   48     for (size_t i = 0; i < 16; i++)
 
   49         message[i] = label.label_bytes[i];
 
   51     // More efficient way to get canonical point rep?
 
   52     std::stringstream stream;
 
   53     stream.rdbuf()->pubsetbuf(((char *)message) + 16, 320);
 
   54     stream << Lambda_copy;
 
   55     size_t written = stream.tellp();
 
   57         message[16 + written++] = 0;
 
   59     crypto_sign_ed25519_amd64_51_30k(
 
   60         signature, &sigmalen, message, 16 + 320, sk.sk_bytes);
 
   62     assert(sigmalen == 64 + 16 + 320);
 
   64     for (size_t i = 0; i < 64; i++)
 
   65         sigma.sig_bytes[i] = signature[i];
 
   71 bool sigVerif<default_r1cs_ppzkadsnark_pp>(
 
   72     const ed25519_vkT &vk,
 
   74     const libff::G2<snark_pp<default_r1cs_ppzkadsnark_pp>> &Lambda,
 
   75     const ed25519_sigT &sig)
 
   77     unsigned long long msglen;
 
   78     unsigned char message[64 + 16 + 320];
 
   79     unsigned char signature[64 + 16 + 320];
 
   81     libff::G2<snark_pp<default_r1cs_ppzkadsnark_pp>> Lambda_copy(Lambda);
 
   82     Lambda_copy.to_affine_coordinates();
 
   84     for (size_t i = 0; i < 64; i++)
 
   85         signature[i] = sig.sig_bytes[i];
 
   87     for (size_t i = 0; i < 16; i++)
 
   88         signature[64 + i] = label.label_bytes[i];
 
   90     // More efficient way to get canonical point rep?
 
   91     std::stringstream stream;
 
   92     stream.rdbuf()->pubsetbuf(((char *)signature) + 64 + 16, 320);
 
   93     stream << Lambda_copy;
 
   94     size_t written = stream.tellp();
 
   96         signature[64 + 16 + written++] = 0;
 
   98     int res = crypto_sign_ed25519_amd64_51_30k_open(
 
   99         message, &msglen, signature, 64 + 16 + 320, vk.vk_bytes);
 
  104 bool sigBatchVerif<default_r1cs_ppzkadsnark_pp>(
 
  105     const ed25519_vkT &vk,
 
  106     const std::vector<labelT> &labels,
 
  107     const std::vector<libff::G2<snark_pp<default_r1cs_ppzkadsnark_pp>>>
 
  109     const std::vector<ed25519_sigT> &sigs)
 
  111     std::stringstream stream;
 
  113     assert(labels.size() == Lambdas.size());
 
  114     assert(labels.size() == sigs.size());
 
  116     unsigned long long msglen[labels.size()];
 
  117     unsigned long long siglen[labels.size()];
 
  118     unsigned char *messages[labels.size()];
 
  119     unsigned char *signatures[labels.size()];
 
  120     unsigned char *pks[labels.size()];
 
  122     unsigned char pk_copy[32];
 
  123     for (size_t i = 0; i < 32; i++) {
 
  124         pk_copy[i] = vk.vk_bytes[i];
 
  127     unsigned char *messagemem =
 
  128         (unsigned char *)malloc(labels.size() * (64 + 16 + 320));
 
  129     assert(messagemem != NULL);
 
  130     unsigned char *signaturemem =
 
  131         (unsigned char *)malloc(labels.size() * (64 + 16 + 320));
 
  132     assert(signaturemem != NULL);
 
  134     for (size_t i = 0; i < labels.size(); i++) {
 
  135         siglen[i] = 64 + 16 + 320;
 
  136         messages[i] = messagemem + (64 + 16 + 320) * i;
 
  137         signatures[i] = signaturemem + (64 + 16 + 320) * i;
 
  140         for (size_t j = 0; j < 64; j++)
 
  141             signaturemem[i * (64 + 16 + 320) + j] = sigs[i].sig_bytes[j];
 
  143         for (size_t j = 0; j < 16; j++)
 
  144             signaturemem[i * (64 + 16 + 320) + 64 + j] =
 
  145                 labels[i].label_bytes[j];
 
  147         // More efficient way to get canonical point rep?
 
  148         libff::G2<snark_pp<default_r1cs_ppzkadsnark_pp>> Lambda_copy(
 
  150         Lambda_copy.to_affine_coordinates();
 
  152         stream.rdbuf()->pubsetbuf(
 
  153             (char *)(signaturemem + i * (64 + 16 + 320) + 64 + 16), 320);
 
  154         stream << Lambda_copy;
 
  155         size_t written = stream.tellp();
 
  156         while (written < 320)
 
  157             signaturemem[i * (64 + 16 + 320) + 64 + 16 + written++] = 0;
 
  160     int res = crypto_sign_ed25519_amd64_51_30k_open_batch(
 
  161         messages, msglen, signatures, siglen, pks, labels.size());
 
  166 } // namespace libsnark