forked from data61/MP-SPDZ
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsign.hpp
152 lines (139 loc) · 4.49 KB
/
sign.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/*
* sign.hpp
*
*/
#ifndef ECDSA_SIGN_HPP_
#define ECDSA_SIGN_HPP_
//#include "CurveElement.h"
#include "P256Element.h"
#include "Tools/Bundle.h"
#include "preprocessing.hpp"
class EcSignature
{
public:
P256Element R;
P256Element::Scalar s;
};
/*
inline
CurveElement::Scalar hash_to_scalar(const unsigned char* message, size_t length, CurveElement::Scalar rx, CurveElement pk)
{
crypto_hash_sha512_state state;
crypto_hash_sha512_init(&state);
crypto_hash_sha512_update(&state, (unsigned char*) rx.get_ptr(),
crypto_core_ristretto255_SCALARBYTES);
crypto_hash_sha512_update(&state, pk.get(), crypto_core_ristretto255_BYTES);
crypto_hash_sha512_update(&state, message, length);
unsigned char hash[crypto_hash_sha512_BYTES];
crypto_hash_sha512_final(&state, hash);
auto& tmp = bigint::tmp;
mpz_import(tmp.get_mpz_t(), crypto_hash_sha512_BYTES, -1, 1, 0, 0, hash);
return tmp;
}
*/
inline P256Element::Scalar hash_to_scalar(const unsigned char* message, size_t length)
{
P256Element::Scalar res;
assert(res.size() == crypto_hash_sha256_BYTES);
crypto_hash_sha256((unsigned char*) res.get_ptr(), message, length);
res.zero_overhang();
return res;
}
template<template<class U> class T>
EcSignature sign(const unsigned char* message, size_t length,
EcTuple<T> tuple,
typename T<P256Element::Scalar>::MAC_Check& MC, Player& P,
P256Element pk,
T<P256Element::Scalar> sk = {},
SubProcessor<T<P256Element::Scalar>>* proc = 0)
{
(void) pk;
Timer timer;
timer.start();
size_t start = P.sent;
auto stats = P.comm_stats;
EcSignature signature;
signature.R = tuple.R;
T<P256Element::Scalar> prod = tuple.b;
if (proc)
{
auto& protocol = proc->protocol;
protocol.init_mul(proc);
protocol.prepare_mul(sk, tuple.a);
protocol.exchange();
prod = protocol.finalize_mul();
}
auto rx = tuple.R.x();
signature.s = MC.open(
tuple.a * hash_to_scalar(message, length) + prod * rx, P);
cout << "Minimal signing took " << timer.elapsed() * 1e3 << " ms and sending "
<< (P.sent - start) << " bytes" << endl;
auto diff = (P.comm_stats - stats);
diff.print(true);
return signature;
}
inline
EcSignature sign(const unsigned char* message, size_t length, P256Element::Scalar sk)
{
EcSignature signature;
auto k = SeededPRNG().get<P256Element::Scalar>();
auto inv_k = k;
inv_k.invert();
signature.R = k;
auto rx = signature.R.x();
signature.s = inv_k * (hash_to_scalar(message, length) + rx * sk);
return signature;
}
inline
void check(EcSignature signature, const unsigned char* message, size_t length,
P256Element pk)
{
Timer timer;
timer.start();
signature.s.check();
signature.R.check();
P256Element::Scalar w;
w.invert(signature.s);
auto u1 = hash_to_scalar(message, length) * w;
auto u2 = signature.R.x() * w;
assert(P256Element(u1) + pk * u2 == signature.R);
cout << "Offline checking took " << timer.elapsed() * 1e3 << " ms" << endl;
}
template<template<class U> class T>
void sign_benchmark(vector<EcTuple<T>>& tuples, T<P256Element::Scalar> sk,
typename T<P256Element::Scalar>::MAC_Check& MCp, Player& P,
EcdsaOptions& opts,
SubProcessor<T<P256Element::Scalar>>* proc = 0)
{
unsigned char message[1024];
GlobalPRNG(P).get_octets(message, 1024);
typename T<P256Element>::Direct_MC MCc(MCp.get_alphai());
// synchronize
Bundle<octetStream> bundle(P);
P.Broadcast_Receive(bundle, true);
Timer timer;
timer.start();
auto stats = P.comm_stats;
P256Element pk = MCc.open(sk, P);
MCc.Check(P);
cout << "Public key generation took " << timer.elapsed() * 1e3 << " ms" << endl;
(P.comm_stats - stats).print(true);
for (size_t i = 0; i < min(10lu, tuples.size()); i++)
{
check(sign(message, 1 << i, tuples[i], MCp, P, pk, sk, proc), message,
1 << i, pk);
if (not opts.check_open)
continue;
Timer timer;
timer.start();
auto& check_player = MCp.get_check_player(P);
auto stats = check_player.comm_stats;
auto start = check_player.sent;
MCp.Check(P);
cout << "Online checking took " << timer.elapsed() * 1e3 << " ms and sending "
<< (check_player.sent - start) << " bytes" << endl;
auto diff = (check_player.comm_stats - stats);
diff.print();
}
}
#endif /* ECDSA_SIGN_HPP_ */