Skip to content

Commit 0b49eda

Browse files
committed
Use libsodium's s < L check, instead checking that libsodium checks that.
Adaptation coming from zcash@2902ac7ce8e754d09a5137cba82d8af10c172977
1 parent b8d4c8e commit 0b49eda

4 files changed

Lines changed: 46 additions & 0 deletions

File tree

src/init.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1217,6 +1217,11 @@ bool AppInitSanityChecks()
12171217
{
12181218
// ********************************************************* Step 4: sanity checks
12191219

1220+
// Initialize libsodium
1221+
if (init_and_check_sodium() == -1) {
1222+
return false;
1223+
}
1224+
12201225
// Initialize elliptic curve code
12211226
RandomInit();
12221227
ECC_Start();

src/sapling/sodium_sanity.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,44 @@
1010

1111
#include <sodium.h>
1212

13+
int init_and_check_sodium()
14+
{
15+
if (sodium_init() == -1) {
16+
return -1;
17+
}
18+
19+
// What follows is a runtime test that ensures the version of libsodium
20+
// we're linked against checks that signatures are canonical (s < L).
21+
const unsigned char message[1] = { 0 };
22+
23+
unsigned char pk[crypto_sign_PUBLICKEYBYTES];
24+
unsigned char sk[crypto_sign_SECRETKEYBYTES];
25+
unsigned char sig[crypto_sign_BYTES];
26+
27+
crypto_sign_keypair(pk, sk);
28+
crypto_sign_detached(sig, NULL, message, sizeof(message), sk);
29+
30+
assert(crypto_sign_verify_detached(sig, message, sizeof(message), pk) == 0);
31+
32+
// Copied from libsodium/crypto_sign/ed25519/ref10/open.c
33+
static const unsigned char L[32] =
34+
{ 0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58,
35+
0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14,
36+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
37+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 };
38+
39+
// Add L to S, which starts at sig[32].
40+
unsigned int s = 0;
41+
for (size_t i = 0; i < 32; i++) {
42+
s = sig[32 + i] + L[i] + (s >> 8);
43+
sig[32 + i] = s & 0xff;
44+
}
45+
46+
assert(crypto_sign_verify_detached(sig, message, sizeof(message), pk) != 0);
47+
48+
return 0;
49+
}
50+
1351
void TestLibsodiumEd25519SignatureVerification(
1452
const std::string &scope,
1553
const std::string &msg,

src/sapling/sodium_sanity.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#ifndef PIVX_SODIUM_SANITY_H
66
#define PIVX_SODIUM_SANITY_H
77

8+
int init_and_check_sodium();
89
void libsodium_sanity_test();
910

1011
#endif //PIVX_SODIUM_SANITY_H

src/test/test_pivx.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "net_processing.h"
1616
#include "rpc/server.h"
1717
#include "rpc/register.h"
18+
#include "sapling/sodium_sanity.h"
1819
#include "script/sigcache.h"
1920
#include "sporkdb.h"
2021
#include "txmempool.h"
@@ -40,6 +41,7 @@ std::ostream& operator<<(std::ostream& os, const uint256& num)
4041

4142
BasicTestingSetup::BasicTestingSetup()
4243
{
44+
assert(init_and_check_sodium() != -1);
4345
ECC_Start();
4446
SetupEnvironment();
4547
InitSignatureCache();

0 commit comments

Comments
 (0)