Clearmatics Libsnark  0.1
C++ library for zkSNARK proofs
ed25519_signature.tcc
Go to the documentation of this file.
1 /** @file
2  *****************************************************************************
3 
4  Fast batch verification signature for ADSNARK.
5 
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  *****************************************************************************/
11 
12 /** @file
13  *****************************************************************************
14  * @author This file was deed to libsnark by Manuel Barbosa.
15  * @copyright MIT license (see LICENSE file)
16  *****************************************************************************/
17 
18 #include "depends/libsnark-supercop/include/crypto_sign.h"
19 
20 #include <libsnark/common/default_types/r1cs_ppzkadsnark_pp.hpp>
21 
22 namespace libsnark
23 {
24 
25 template<>
26 kpT<default_r1cs_ppzkadsnark_pp> sigGen<default_r1cs_ppzkadsnark_pp>(void)
27 {
28  kpT<default_r1cs_ppzkadsnark_pp> keys;
29  crypto_sign_ed25519_amd64_51_30k_keypair(
30  keys.vk.vk_bytes, keys.sk.sk_bytes);
31  return keys;
32 }
33 
34 template<>
35 ed25519_sigT sigSign<default_r1cs_ppzkadsnark_pp>(
36  const ed25519_skT &sk,
37  const labelT &label,
38  const libff::G2<snark_pp<default_r1cs_ppzkadsnark_pp>> &Lambda)
39 {
40  ed25519_sigT sigma;
41  unsigned long long sigmalen;
42  unsigned char signature[64 + 16 + 320];
43  unsigned char message[16 + 320];
44 
45  libff::G2<snark_pp<default_r1cs_ppzkadsnark_pp>> Lambda_copy(Lambda);
46  Lambda_copy.to_affine_coordinates();
47 
48  for (size_t i = 0; i < 16; i++)
49  message[i] = label.label_bytes[i];
50 
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();
56  while (written < 320)
57  message[16 + written++] = 0;
58 
59  crypto_sign_ed25519_amd64_51_30k(
60  signature, &sigmalen, message, 16 + 320, sk.sk_bytes);
61 
62  assert(sigmalen == 64 + 16 + 320);
63 
64  for (size_t i = 0; i < 64; i++)
65  sigma.sig_bytes[i] = signature[i];
66 
67  return sigma;
68 }
69 
70 template<>
71 bool sigVerif<default_r1cs_ppzkadsnark_pp>(
72  const ed25519_vkT &vk,
73  const labelT &label,
74  const libff::G2<snark_pp<default_r1cs_ppzkadsnark_pp>> &Lambda,
75  const ed25519_sigT &sig)
76 {
77  unsigned long long msglen;
78  unsigned char message[64 + 16 + 320];
79  unsigned char signature[64 + 16 + 320];
80 
81  libff::G2<snark_pp<default_r1cs_ppzkadsnark_pp>> Lambda_copy(Lambda);
82  Lambda_copy.to_affine_coordinates();
83 
84  for (size_t i = 0; i < 64; i++)
85  signature[i] = sig.sig_bytes[i];
86 
87  for (size_t i = 0; i < 16; i++)
88  signature[64 + i] = label.label_bytes[i];
89 
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();
95  while (written < 320)
96  signature[64 + 16 + written++] = 0;
97 
98  int res = crypto_sign_ed25519_amd64_51_30k_open(
99  message, &msglen, signature, 64 + 16 + 320, vk.vk_bytes);
100  return (res == 0);
101 }
102 
103 template<>
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>>>
108  &Lambdas,
109  const std::vector<ed25519_sigT> &sigs)
110 {
111  std::stringstream stream;
112 
113  assert(labels.size() == Lambdas.size());
114  assert(labels.size() == sigs.size());
115 
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()];
121 
122  unsigned char pk_copy[32];
123  for (size_t i = 0; i < 32; i++) {
124  pk_copy[i] = vk.vk_bytes[i];
125  }
126 
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);
133 
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;
138  pks[i] = pk_copy;
139 
140  for (size_t j = 0; j < 64; j++)
141  signaturemem[i * (64 + 16 + 320) + j] = sigs[i].sig_bytes[j];
142 
143  for (size_t j = 0; j < 16; j++)
144  signaturemem[i * (64 + 16 + 320) + 64 + j] =
145  labels[i].label_bytes[j];
146 
147  // More efficient way to get canonical point rep?
148  libff::G2<snark_pp<default_r1cs_ppzkadsnark_pp>> Lambda_copy(
149  Lambdas[i]);
150  Lambda_copy.to_affine_coordinates();
151  stream.clear();
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;
158  }
159 
160  int res = crypto_sign_ed25519_amd64_51_30k_open_batch(
161  messages, msglen, signatures, siglen, pks, labels.size());
162 
163  return (res == 0);
164 }
165 
166 } // namespace libsnark