Skip to content

Commit

Permalink
Merge pull request #3377 from sisuresh/cap21-40-2
Browse files Browse the repository at this point in the history
Protocol 19 - CAP-0021 and CAP-0040

Reviewed-by: MonsieurNicolas
  • Loading branch information
latobarita authored Apr 14, 2022
2 parents 4c7c563 + 0e5c9e6 commit 27c798e
Show file tree
Hide file tree
Showing 82 changed files with 25,582 additions and 22,480 deletions.
36 changes: 32 additions & 4 deletions src/catchup/simulation/TxSimApplyTransactionsWork.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -291,16 +291,31 @@ TxSimApplyTransactionsWork::addSignerKeys(
return;
}

for (auto const& signer : account.current().data.account().signers)
{
if (signer.key.type() == SIGNER_KEY_TYPE_ED25519)
auto maybeAddKey = [&](SignerKey const& signer) {
if (signer.type() == SIGNER_KEY_TYPE_ED25519)
{
auto pubKey = KeyUtils::convertKey<PublicKey>(signer.key);
auto pubKey = KeyUtils::convertKey<PublicKey>(signer);
if (hasSig(pubKey, sigs, txHash))
{
keys.emplace(generateScaledSecret(pubKey, partition));
}
}
};

for (auto const& signer : account.current().data.account().signers)
{
maybeAddKey(signer.key);
}

auto const& env = mUpgradeProtocol
? txbridge::convertForV13(*mTransactionIter)
: *mTransactionIter;
if (env.type() == ENVELOPE_TYPE_TX && env.v1().tx.cond.type() == PRECOND_V2)
{
for (auto const& signerKey : env.v1().tx.cond.v2().extraSigners)
{
maybeAddKey(signerKey);
}
}
}

Expand Down Expand Up @@ -469,6 +484,19 @@ TxSimApplyTransactionsWork::scaleLedger(
mutateScaledAccountID(newEnv.feeBump().tx.feeSource, partition);
newTxHash = simulateSigs(outerSigs, outerTxKeys, false);
}
else if (env.type() == ENVELOPE_TYPE_TX &&
env.v1().tx.cond.type() == PRECOND_V2)
{
newEnv.v1().tx.cond.v2().extraSigners.clear();
for (auto const& signerKey : env.v1().tx.cond.v2().extraSigners)
{
if (signerKey.type() == SIGNER_KEY_TYPE_ED25519)
{
newEnv.v1().tx.cond.v2().extraSigners.emplace_back(
generateScaledEd25519Signer(signerKey, partition));
}
}
}

// These are not exactly accurate, but sufficient to check result codes
auto newRes = *mResultIter;
Expand Down
2 changes: 2 additions & 0 deletions src/crypto/KeyUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ KeyUtils::getKeyVersionSize(strKey::StrKeyVersionByte keyVersion)
case strKey::STRKEY_PRE_AUTH_TX:
case strKey::STRKEY_HASH_X:
return 32U;
case strKey::STRKEY_ED25519_SIGNED_PAYLOAD:
return 96U; // 32 bytes for the key and 64 bytes for the payload
default:
throw std::invalid_argument("invalid key version: " +
std::to_string(keyVersion));
Expand Down
23 changes: 16 additions & 7 deletions src/crypto/KeyUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,17 @@ template <typename T> struct KeyFunctions

static std::string getKeyTypeName();
static bool getKeyVersionIsSupported(strKey::StrKeyVersionByte keyVersion);
static bool
getKeyVersionIsVariableLength(strKey::StrKeyVersionByte keyVersion);
static typename getKeyTypeEnum::type
toKeyType(strKey::StrKeyVersionByte keyVersion);
static strKey::StrKeyVersionByte
toKeyVersion(typename getKeyTypeEnum::type keyType);
static uint256& getKeyValue(T& key);
static uint256 const& getKeyValue(T const& key);
static uint256& getEd25519Value(T& key);
static uint256 const& getEd25519Value(T const& key);

static std::vector<uint8_t> getKeyValue(T const& key);
static void setKeyValue(T& key, std::vector<uint8_t> const& data);
};

// signer key utility functions
Expand Down Expand Up @@ -84,15 +89,18 @@ fromStrKey(std::string const& s)

strKey::StrKeyVersionByte ver =
static_cast<strKey::StrKeyVersionByte>(verByte);
if (!KeyFunctions<T>::getKeyVersionIsSupported(ver) ||
(k.size() != getKeyVersionSize(ver)) ||
(s.size() != strKey::getStrKeySize(getKeyVersionSize(ver))))

bool fixedSizeKeyValid =
!KeyFunctions<T>::getKeyVersionIsVariableLength(ver) &&
(k.size() != getKeyVersionSize(ver));
if (fixedSizeKeyValid || !KeyFunctions<T>::getKeyVersionIsSupported(ver) ||
s.size() != strKey::getStrKeySize(k.size()))
{
throw std::invalid_argument("bad " + KeyFunctions<T>::getKeyTypeName());
}

key.type(KeyFunctions<T>::toKeyType(ver));
std::copy(k.begin(), k.end(), KeyFunctions<T>::getKeyValue(key).begin());
KeyFunctions<T>::setKeyValue(key, k);
return key;
}

Expand All @@ -111,7 +119,8 @@ convertKey(F const& fromKey)
T toKey;
toKey.type(KeyFunctions<T>::toKeyType(
KeyFunctions<F>::toKeyVersion(fromKey.type())));
KeyFunctions<T>::getKeyValue(toKey) = KeyFunctions<F>::getKeyValue(fromKey);
KeyFunctions<T>::getEd25519Value(toKey) =
KeyFunctions<F>::getEd25519Value(fromKey);
return toKey;
}
}
Expand Down
31 changes: 29 additions & 2 deletions src/crypto/SecretKey.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,13 @@ KeyFunctions<PublicKey>::getKeyVersionIsSupported(
}
}

bool
KeyFunctions<PublicKey>::getKeyVersionIsVariableLength(
strKey::StrKeyVersionByte keyVersion)
{
return false;
}

PublicKeyType
KeyFunctions<PublicKey>::toKeyType(strKey::StrKeyVersionByte keyVersion)
{
Expand All @@ -368,7 +375,7 @@ KeyFunctions<PublicKey>::toKeyVersion(PublicKeyType keyType)
}

uint256&
KeyFunctions<PublicKey>::getKeyValue(PublicKey& key)
KeyFunctions<PublicKey>::getEd25519Value(PublicKey& key)
{
switch (key.type())
{
Expand All @@ -380,7 +387,7 @@ KeyFunctions<PublicKey>::getKeyValue(PublicKey& key)
}

uint256 const&
KeyFunctions<PublicKey>::getKeyValue(PublicKey const& key)
KeyFunctions<PublicKey>::getEd25519Value(PublicKey const& key)
{
switch (key.type())
{
Expand All @@ -391,6 +398,26 @@ KeyFunctions<PublicKey>::getKeyValue(PublicKey const& key)
}
}

std::vector<uint8_t>
KeyFunctions<PublicKey>::getKeyValue(PublicKey const& key)
{
return xdr::xdr_to_opaque(getEd25519Value(key));
}

void
KeyFunctions<PublicKey>::setKeyValue(PublicKey& key,
std::vector<uint8_t> const& data)
{
switch (key.type())
{
case PUBLIC_KEY_TYPE_ED25519:
xdr::xdr_from_opaque(data, key.ed25519());
break;
default:
throw CryptoError("invalid public key type");
}
}

bool
PubKeyUtils::verifySig(PublicKey const& key, Signature const& signature,
ByteSlice const& bin)
Expand Down
9 changes: 7 additions & 2 deletions src/crypto/SecretKey.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,15 @@ template <> struct KeyFunctions<PublicKey>

static std::string getKeyTypeName();
static bool getKeyVersionIsSupported(strKey::StrKeyVersionByte keyVersion);
static bool
getKeyVersionIsVariableLength(strKey::StrKeyVersionByte keyVersion);
static PublicKeyType toKeyType(strKey::StrKeyVersionByte keyVersion);
static strKey::StrKeyVersionByte toKeyVersion(PublicKeyType keyType);
static uint256& getKeyValue(PublicKey& key);
static uint256 const& getKeyValue(PublicKey const& key);
static uint256& getEd25519Value(PublicKey& key);
static uint256 const& getEd25519Value(PublicKey const& key);

static std::vector<uint8_t> getKeyValue(PublicKey const& key);
static void setKeyValue(PublicKey& key, std::vector<uint8_t> const& data);
};

// public key utility functions
Expand Down
76 changes: 68 additions & 8 deletions src/crypto/SignerKey.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include "crypto/StrKey.h"
#include "xdr/Stellar-types.h"
#include "xdrpp/marshal.h"

#include <sodium/crypto_sign.h>

Expand All @@ -30,11 +31,32 @@ KeyFunctions<SignerKey>::getKeyVersionIsSupported(
return true;
case strKey::STRKEY_HASH_X:
return true;
case strKey::STRKEY_ED25519_SIGNED_PAYLOAD:
return true;
default:
return false;
}
}

bool
KeyFunctions<SignerKey>::getKeyVersionIsVariableLength(
strKey::StrKeyVersionByte keyVersion)
{
switch (keyVersion)
{
case strKey::STRKEY_PUBKEY_ED25519:
return false;
case strKey::STRKEY_PRE_AUTH_TX:
return false;
case strKey::STRKEY_HASH_X:
return false;
case strKey::STRKEY_ED25519_SIGNED_PAYLOAD:
return true;
default:
throw std::invalid_argument("invalid signer key type");
}
}

typename KeyFunctions<SignerKey>::getKeyTypeEnum::type
KeyFunctions<SignerKey>::toKeyType(strKey::StrKeyVersionByte keyVersion)
{
Expand All @@ -46,6 +68,8 @@ KeyFunctions<SignerKey>::toKeyType(strKey::StrKeyVersionByte keyVersion)
return SignerKeyType::SIGNER_KEY_TYPE_PRE_AUTH_TX;
case strKey::STRKEY_HASH_X:
return SignerKeyType::SIGNER_KEY_TYPE_HASH_X;
case strKey::STRKEY_ED25519_SIGNED_PAYLOAD:
return SignerKeyType::SIGNER_KEY_TYPE_ED25519_SIGNED_PAYLOAD;
default:
throw std::invalid_argument("invalid signer key type");
}
Expand All @@ -62,40 +86,76 @@ KeyFunctions<SignerKey>::toKeyVersion(SignerKeyType keyType)
return strKey::STRKEY_PRE_AUTH_TX;
case SignerKeyType::SIGNER_KEY_TYPE_HASH_X:
return strKey::STRKEY_HASH_X;
case SignerKeyType::SIGNER_KEY_TYPE_ED25519_SIGNED_PAYLOAD:
return strKey::STRKEY_ED25519_SIGNED_PAYLOAD;
default:
throw std::invalid_argument("invalid signer key type");
}
}

uint256&
KeyFunctions<SignerKey>::getKeyValue(SignerKey& key)
KeyFunctions<SignerKey>::getEd25519Value(SignerKey& key)
{
switch (key.type())
{
case SIGNER_KEY_TYPE_ED25519:
return key.ed25519();
case SIGNER_KEY_TYPE_PRE_AUTH_TX:
return key.preAuthTx();
case SIGNER_KEY_TYPE_HASH_X:
return key.hashX();
default:
throw std::invalid_argument("invalid signer key type");
}
}

uint256 const&
KeyFunctions<SignerKey>::getKeyValue(SignerKey const& key)
KeyFunctions<SignerKey>::getEd25519Value(SignerKey const& key)
{
switch (key.type())
{
case SIGNER_KEY_TYPE_ED25519:
return key.ed25519();
default:
throw std::invalid_argument("invalid signer key type");
}
}

std::vector<uint8_t>
KeyFunctions<SignerKey>::getKeyValue(SignerKey const& key)
{
switch (key.type())
{
case SIGNER_KEY_TYPE_ED25519:
return xdr::xdr_to_opaque(key.ed25519());
case SIGNER_KEY_TYPE_PRE_AUTH_TX:
return key.preAuthTx();
return xdr::xdr_to_opaque(key.preAuthTx());
case SIGNER_KEY_TYPE_HASH_X:
return key.hashX();
return xdr::xdr_to_opaque(key.hashX());
case SIGNER_KEY_TYPE_ED25519_SIGNED_PAYLOAD:
return xdr::xdr_to_opaque(key.ed25519SignedPayload());
default:
throw std::invalid_argument("invalid signer key type");
}
}

void
KeyFunctions<SignerKey>::setKeyValue(SignerKey& key,
std::vector<uint8_t> const& data)
{
switch (key.type())
{
case SIGNER_KEY_TYPE_ED25519:
xdr::xdr_from_opaque(data, key.ed25519());
break;
case SIGNER_KEY_TYPE_PRE_AUTH_TX:
xdr::xdr_from_opaque(data, key.preAuthTx());
break;
case SIGNER_KEY_TYPE_HASH_X:
xdr::xdr_from_opaque(data, key.hashX());
break;
case SIGNER_KEY_TYPE_ED25519_SIGNED_PAYLOAD:
xdr::xdr_from_opaque(data, key.ed25519SignedPayload());
break;
default:
throw std::invalid_argument("invalid signer key type");
}
}

}
9 changes: 7 additions & 2 deletions src/crypto/SignerKey.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,14 @@ template <> struct KeyFunctions<SignerKey>

static std::string getKeyTypeName();
static bool getKeyVersionIsSupported(strKey::StrKeyVersionByte keyVersion);
static bool
getKeyVersionIsVariableLength(strKey::StrKeyVersionByte keyVersion);
static SignerKeyType toKeyType(strKey::StrKeyVersionByte keyVersion);
static strKey::StrKeyVersionByte toKeyVersion(SignerKeyType keyType);
static uint256& getKeyValue(SignerKey& key);
static uint256 const& getKeyValue(SignerKey const& key);
static uint256& getEd25519Value(SignerKey& key);
static uint256 const& getEd25519Value(SignerKey const& key);

static std::vector<uint8_t> getKeyValue(SignerKey const& key);
static void setKeyValue(SignerKey& key, std::vector<uint8_t> const& data);
};
}
10 changes: 10 additions & 0 deletions src/crypto/SignerKeyUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,15 @@ hashXKey(ByteSlice const& bs)
sk.hashX() = sha256(bs);
return sk;
}

SignerKey
ed25519PayloadKey(uint256 const& ed25519, xdr::opaque_vec<64> const& payload)
{
SignerKey sk;
sk.type(SIGNER_KEY_TYPE_ED25519_SIGNED_PAYLOAD);
sk.ed25519SignedPayload().ed25519 = ed25519;
sk.ed25519SignedPayload().payload = payload;
return sk;
}
}
}
4 changes: 4 additions & 0 deletions src/crypto/SignerKeyUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
// under the Apache License, Version 2.0. See the COPYING file at the root
// of this distribution or at http://www.apache.org/licenses/LICENSE-2.0

#include "xdr/Stellar-types.h"

namespace stellar
{

Expand All @@ -18,5 +20,7 @@ namespace SignerKeyUtils
SignerKey preAuthTxKey(TransactionFrame const& tx);
SignerKey preAuthTxKey(FeeBumpTransactionFrame const& tx);
SignerKey hashXKey(ByteSlice const& bs);
SignerKey ed25519PayloadKey(uint256 const& ed25519,
xdr::opaque_vec<64> const& payload);
}
}
9 changes: 5 additions & 4 deletions src/crypto/StrKey.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ namespace strKey
enum StrKeyVersionByte : uint8_t
{
// version bytes - 5 bits only
STRKEY_PUBKEY_ED25519 = 6, // 'G'
STRKEY_SEED_ED25519 = 18, // 'S'
STRKEY_PRE_AUTH_TX = 19, // 'T',
STRKEY_HASH_X = 23 // 'X'
STRKEY_PUBKEY_ED25519 = 6, // 'G'
STRKEY_ED25519_SIGNED_PAYLOAD = 15, // 'P'
STRKEY_SEED_ED25519 = 18, // 'S'
STRKEY_PRE_AUTH_TX = 19, // 'T',
STRKEY_HASH_X = 23 // 'X'
};

// Encode a version byte and ByteSlice into StrKey
Expand Down
Loading

0 comments on commit 27c798e

Please sign in to comment.