mirror of
https://github.com/data61/MP-SPDZ.git
synced 2026-01-09 13:37:58 -05:00
153 lines
4.5 KiB
C++
153 lines
4.5 KiB
C++
/*
|
|
* 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_ */
|