Skip to content

Commit 8d2daf8

Browse files
authored
version 5.3.0 (#13)
1 parent 88d099f commit 8d2daf8

File tree

6 files changed

+241
-2
lines changed

6 files changed

+241
-2
lines changed

CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
cmake_minimum_required( VERSION 3.14 )
1818

19-
project( scl VERSION 5.2.0 DESCRIPTION "Secure Computation Library" )
19+
project( scl VERSION 5.3.0 DESCRIPTION "Secure Computation Library" )
2020

2121
if(NOT CMAKE_BUILD_TYPE)
2222
set(CMAKE_BUILD_TYPE Release)
@@ -99,6 +99,7 @@ if(CMAKE_BUILD_TYPE MATCHES "Debug")
9999
test/scl/util/test_sha3.cc
100100
test/scl/util/test_sha256.cc
101101
test/scl/util/test_traits.cc
102+
test/scl/util/test_ecdsa.cc
102103

103104
test/scl/gf7.cc
104105
test/scl/math/test_mersenne61.cc

RELEASE.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
5.3.0: ECDSA
2+
- Added functionality for creating ECDSA signatures.
3+
4+
5.2.0: Protocol environment extensions
5+
- Make it possible to create "checkpoints" through the protocol environment
6+
clock.
7+
- fix a bug that prevented the documentation from being buildt
8+
- Rename ProtocolEnvironment to Env, and introduce a typedef for backwards
9+
compatability.
10+
111
5.1.2: Style changes
212
- Change naming style of private field members.
313

include/scl/util/iuf_hash.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,16 @@ struct IUFHash {
6464
return Update(data.data(), N);
6565
}
6666

67+
/**
68+
* @brief Update the hash function with the content of a string.
69+
* @param string the string.
70+
* @return the updated Hash object.
71+
*/
72+
IUFHash<HashImpl>& Update(std::string_view string) {
73+
return Update(reinterpret_cast<const unsigned char*>(string.data()),
74+
string.size());
75+
}
76+
6777
/**
6878
* @brief Finalize and return the digest.
6979
* @return a digest.

include/scl/util/sign.h

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
/* SCL --- Secure Computation Library
2+
* Copyright (C) 2023 Anders Dalskov
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU Affero General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU Affero General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU Affero General Public License
15+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
16+
*/
17+
18+
#ifndef SCL_UTIL_SIGN_H
19+
#define SCL_UTIL_SIGN_H
20+
21+
#include <memory>
22+
23+
#include "scl/math/curves/secp256k1.h"
24+
#include "scl/math/ff.h"
25+
26+
namespace scl::util {
27+
28+
/**
29+
* @brief A signature for some signature scheme.
30+
* @tparam SignatureScheme the signature scheme.
31+
*/
32+
template <typename SignatureScheme>
33+
struct Signature;
34+
35+
class ECDSA;
36+
37+
/**
38+
* @brief An ECDSA signature.
39+
*/
40+
template <>
41+
struct Signature<ECDSA> {
42+
private:
43+
using ElementType = math::FF<math::Secp256k1::Order>;
44+
45+
public:
46+
/**
47+
* @brief The size of an ECDSA signature in bytes.
48+
*/
49+
constexpr static std::size_t ByteSize() {
50+
return ElementType::ByteSize() * 2;
51+
}
52+
53+
/**
54+
* @brief Read an ECDSA signature from a buffer.
55+
* @param buf the buffer.
56+
* @return an ECDSA signature.
57+
*/
58+
static Signature<ECDSA> Read(const unsigned char* buf) {
59+
return {ElementType::Read(buf),
60+
ElementType::Read(buf + ElementType::ByteSize())};
61+
}
62+
63+
/**
64+
* @brief Write an ECDSA signature to a stream.
65+
* @param buf the buffer.
66+
*/
67+
void Write(unsigned char* buf) const {
68+
r.Write(buf);
69+
s.Write(buf + ElementType::ByteSize());
70+
}
71+
72+
/**
73+
* @brief The r part of an ECDSA signature.
74+
*/
75+
ElementType r;
76+
77+
/**
78+
* @brief The s part of an ECDSA signature.
79+
*/
80+
ElementType s;
81+
};
82+
83+
/**
84+
* @brief The ECDSA signature scheme.
85+
*/
86+
class ECDSA {
87+
using Curve = math::EC<math::Secp256k1>;
88+
89+
public:
90+
/**
91+
* @brief Public key type. A curve point.
92+
*/
93+
using PublicKey = Curve;
94+
95+
/**
96+
* @brief Secret key type. An element modulo the order of the curve.
97+
*/
98+
using SecretKey = Curve::Order;
99+
100+
/**
101+
* @brief Derive the public key correspond to a given secret key.
102+
* @param secret_key the secret key.
103+
* @return A public key.
104+
*/
105+
static PublicKey Derive(const SecretKey& secret_key) {
106+
return secret_key * PublicKey::Generator();
107+
}
108+
109+
/**
110+
* @brief Sign a message.
111+
* @tparam D a digest type.
112+
* @param secret_key the secret key for signing.
113+
* @param digest the digest to sign.
114+
* @param prg a PRG used to select the nonce in the signature.
115+
* @return an ECDSA signature.
116+
*/
117+
template <typename D>
118+
static Signature<ECDSA> Sign(const SecretKey& secret_key,
119+
const D& digest,
120+
PRG& prg) {
121+
const auto k = Curve::Order::Random(prg);
122+
const auto R = k * PublicKey::Generator();
123+
const auto rx = ConversionFunc(R);
124+
const auto h = DigestToElement<Curve::Order>(digest);
125+
126+
return {rx, k.Inverse() * (h + secret_key * rx)};
127+
}
128+
129+
/**
130+
* @brief Verify a signature.
131+
* @param public_key the public key of the signer.
132+
* @param signature the signature to verify.
133+
* @param digest the digest that was signed.
134+
* @return true if the signature is valid and false otherwise.
135+
*/
136+
template <typename D>
137+
static bool Verify(const PublicKey& public_key,
138+
const Signature<ECDSA>& signature,
139+
const D& digest) {
140+
const auto h = DigestToElement<SecretKey>(digest);
141+
const auto [r, s] = signature;
142+
const auto si = s.Inverse();
143+
const auto R1 = (h * si) * Curve::Generator();
144+
const auto R2 = (r * si) * public_key;
145+
const auto R = R1 + R2;
146+
return !R.PointAtInfinity() && ConversionFunc(R) == r;
147+
}
148+
149+
private:
150+
template <typename T, typename D>
151+
static T DigestToElement(const D& digest) {
152+
if (digest.size() < T::ByteSize()) {
153+
unsigned char buf[T::ByteSize()] = {0};
154+
std::copy(digest.begin(), digest.end(), buf);
155+
return T::Read(buf);
156+
}
157+
return T::Read(digest.data());
158+
}
159+
160+
static Curve::Order ConversionFunc(const PublicKey& R) {
161+
const auto rx_f = R.ToAffine()[0];
162+
unsigned char rx_bytes[Curve::Field::ByteSize()];
163+
rx_f.Write(rx_bytes);
164+
return Curve::Order::Read(rx_bytes);
165+
}
166+
};
167+
168+
} // namespace scl::util
169+
170+
#endif // SCL_UTIL_SIGN_H

test/scl/simulation/test_event.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ std::string ToString(sim::Event* e) {
3232

3333
} // namespace
3434

35-
TEST_CASE("Event", "[sim]") {
35+
TEST_CASE("Simulation Event", "[sim]") {
3636
SECTION("START") {
3737
sim::Event e(sim::Event::Type::START, util::Time::Duration::zero());
3838
REQUIRE(ToString(&e) == "START at 0 ms");

test/scl/util/test_ecdsa.cc

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/* SCL --- Secure Computation Library
2+
* Copyright (C) 2023 Anders Dalskov
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU Affero General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU Affero General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU Affero General Public License
15+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
16+
*/
17+
18+
#include <array>
19+
#include <catch2/catch.hpp>
20+
21+
#include "scl/math/curves/secp256k1.h"
22+
#include "scl/util/hash.h"
23+
#include "scl/util/sign.h"
24+
25+
using namespace scl;
26+
27+
TEST_CASE("ECDSA derive", "[util]") {
28+
auto prg = util::PRG::Create("ecdsa derive");
29+
const auto sk = util::ECDSA::SecretKey::Random(prg);
30+
const auto pk = util::ECDSA::Derive(sk);
31+
REQUIRE(pk == sk * math::EC<math::Secp256k1>::Generator());
32+
}
33+
34+
TEST_CASE("ECDSA sign", "[util]") {
35+
auto prg = util::PRG::Create("ecdsa sign");
36+
const auto m = util::Hash<256>{}.Update("message").Finalize();
37+
const auto sk = util::ECDSA::SecretKey::Random(prg);
38+
const auto sig = util::ECDSA::Sign(sk, m, prg);
39+
40+
const auto pk = util::ECDSA::Derive(sk);
41+
REQUIRE(util::ECDSA::Verify(pk, sig, m));
42+
43+
const std::array<unsigned char, 3> m_small = {1, 2, 3};
44+
const auto sig_small = util::ECDSA::Sign(sk, m_small, prg);
45+
REQUIRE(util::ECDSA::Verify(pk, sig_small, m_small));
46+
47+
REQUIRE_FALSE(util::ECDSA::Verify(pk, sig_small, m));
48+
}

0 commit comments

Comments
 (0)