Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions barretenberg/cpp/bootstrap.sh
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,10 @@ function build_native {
cache_upload barretenberg-$native_preset-$hash.zst build/{bin,lib}
fi
# Always inject version (even for cached binaries) to ensure correct version on release
inject_version build/bin/bb
if [ -f build/bin/bb-avm ]; then
inject_version build/bin/bb-avm
inject_version $(scripts/native-preset-build-dir)/bin/bb

if [ -f $(scripts/native-preset-build-dir)/bin/bb-avm ]; then
inject_version $(scripts/native-preset-build-dir)/bin/bb-avm
fi
}

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,39 @@ Commit hash: 05a381f8b31ae4648e480f1369e911b148216e8b
2. `dsl/acir_format/ecdsa_constraints.cpp`
3. `stdlib/encryption/ecdsa/ecdsa.hpp`
4. `stdlib/encryption/ecdsa/ecdsa_impl.hpp`
5. `crypto/ecdsa/ecdsa.hpp`
6. `crypto/ecdsa/ecdsa_impl.hpp`
7. `crypto/hmac/hmac.hpp`
8. `crypto/hashers/hashers.hpp`


## Brief Summary of Module

The files above contain our implementation of the ECDSA verification algorithm and its exposure to Noir. For more details about the algorithm see the documentation in `stdlib/encryption/ecdsa/ecdsa_impl.hpp`, while for details about the usage via Noir see the documentation in `dsl/acir_format/ecdsa_constraints.hpp` and `dsl/acir_format/ecdsa_constraints.cpp`
The files 1. to 4. above contain our implementation of the ECDSA verification algorithm and its exposure to Noir. For more details about the algorithm see the documentation in `stdlib/encryption/ecdsa/ecdsa_impl.hpp`, while for details about the usage via Noir see the documentation in `dsl/acir_format/ecdsa_constraints.hpp` and `dsl/acir_format/ecdsa_constraints.cpp`

Files 3. and 4. implement ECDSA verification, while 1. and 2. expose usage of the algorithm to Noir.

Files 5. to 6. contain our native implementation of:
- ECDSA signature algorithm
- ECDSA verification algorithm
- ECDSA public key recovery algorithm

#### HMAC
HMAC (Hash-based Message Authentication Code) is a cryptographic authentication mechanism. It is used within ECDSA for deterministic nonce generation (RFC 6979) to prevent vulnerabilities from weak random number generators.

File 7. contains our native implementation of HMAC and of deterministic nonce derivation following RFC6979, see links in the code.

#### Hashers
The hashers module provides uniform wrapper interfaces around different hash function implementations (SHA256, BLAKE2s, Keccak256). These wrappers allow ECDSA and other signature schemes to be templated on the hash function type, providing consistent `hash()` interfaces and metadata (BLOCK_SIZE, OUTPUT_SIZE) across different hash algorithms.


## Test Files
1. `dsl/acir_format/ecdsa_constraints.test.cpp`
2. `stdlib/encryption/ecdsa/ecdsa.test.cpp`
3. `stdlib/encryption/ecdsa/ecdsa_tests_data.hpp`
4. `crypto/hmac/hmac.test.cpp`
5. `crypto/ecdsa/ecdsa.test.cpp`
5. `crypto/ecdsa/hashers.test.cpp`

## Security Mechanisms

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ cd ..
pinned_short_hash="189f0026"
pinned_chonk_inputs_url="https://aztec-ci-artifacts.s3.us-east-2.amazonaws.com/protocol/bb-chonk-inputs-${pinned_short_hash}.tar.gz"

script_path="$(cd "$(dirname "${BASH_SOURCE[0]}")/scripts" && pwd)/$(basename "${BASH_SOURCE[0]}")"
script_path="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/$(basename "${BASH_SOURCE[0]}")"

function update_pinned_hash_in_script {
local new_hash=$1
Expand Down Expand Up @@ -229,7 +229,14 @@ else
echo "No VK changes detected. Short hash is: ${pinned_short_hash}"
elif [[ $exit_code -eq 1 ]]; then
# All flows had VK changes
echo "VK changes detected. Please re-run the script with --update_inputs"
echo ""
echo "VK changes detected!"
echo "To acknowledge and auto-regenerate, add a commit to your PR:"
echo ' git commit --allow-empty -m "VK-UPDATE: <explanation of why VKs changed>"'
echo ""
echo "CI will automatically regenerate and commit the updated VKs on the next ci-fast/ci-full run."
echo "If running ci-barretenberg, add the ci-full label to trigger a full CI run."
echo "To update locally instead, re-run with --update_inputs."
exit 1
else
# At least one real error
Expand Down
1 change: 1 addition & 0 deletions barretenberg/cpp/src/barretenberg/crypto/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
add_subdirectory(hmac)
add_subdirectory(hashers)
add_subdirectory(blake2s)
add_subdirectory(blake3s)
add_subdirectory(generators)
Expand Down
49 changes: 45 additions & 4 deletions barretenberg/cpp/src/barretenberg/crypto/ecdsa/ecdsa.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// === AUDIT STATUS ===
// internal: { status: Planned, auditors: [Federico], commit: }
// internal: { status: Completed, auditors: [Federico], commit: }
// external_1: { status: not started, auditors: [], commit: }
// external_2: { status: not started, auditors: [], commit: }
// =====================
Expand All @@ -15,9 +15,14 @@
#include <string>

namespace bb::crypto {

static constexpr int ECDSA_RECOVERY_ID_OFFSET = 27;
static constexpr int ECDSA_R_FINITENESS_OFFSET = 2;

template <typename Fr, typename G1> struct ecdsa_key_pair {
Fr private_key;
typename G1::affine_element public_key;
G1::affine_element public_key;

// For serialization, update with any new fields
MSGPACK_FIELDS(private_key, public_key);
};
Expand All @@ -26,22 +31,58 @@ struct ecdsa_signature {
std::array<uint8_t, 32> r;
std::array<uint8_t, 32> s;
uint8_t v;

// For serialization, update with any new fields
MSGPACK_FIELDS(r, s, v);
};

/**
* @brief Generate the ECDSA for the message using the provided account key pair and hash function
*
*/
template <typename Hash, typename Fq, typename Fr, typename G1>
ecdsa_signature ecdsa_construct_signature(const std::string& message, const ecdsa_key_pair<Fr, G1>& account);

/**
* @brief Given a message and a valid signature with recovery_id, recover the public key whose private key was used to
* sign the message
*
* @details Given \f$(m, (r, s))\f$ a valid signature for message m, we can recover up to four public keys for which
* this is a valid signature: a public key P is valid if \f$H(m) \cdot s^{-1} G + r \cdot s^{-1} P = \pm R\f$, where R
* is the point on the curve with x-coordinate equal to r. Given r, there can be two points R with that x-coordinate.
* Solving the equation for \f$P\f$, gives \f$P = r^{-1} \cdot s \cdot (- H(m) \cdot s^{-1} G + \pm R)$, which means we
* have up to four possibilities for \f$P\f$. We use a recovery_id \f$v\f$ to select which of the four public keys to
* get. The mapping is: recovery_id = offset (=27) +
* y is even && x < |Fr| --> 0
* y is odd && x < |Fr| --> 1
* y is even && |Fr| <= x < |Fq| --> 2
* y is odd && |Fr| <= x < |Fq| --> 3
*
* @note We enforce the signature to have low-s: meaning s < (Fr::modulus + 1) / 2. This means that if s is flipped, the
* effective nonce point R becomes -R, which has the opposite y-parity. We take this into account when generating the
* recovery_id.
*/
template <typename Hash, typename Fq, typename Fr, typename G1>
typename G1::affine_element ecdsa_recover_public_key(const std::string& message, const ecdsa_signature& sig);

// TODO(https://github.com/AztecProtocol/barretenberg/issues/659)
/**
* @brief Verify the ECDSA signature for the message using the provided public key and hash function
*
*/
template <typename Hash, typename Fq, typename Fr, typename G1>
bool ecdsa_verify_signature(const std::string& message,
const typename G1::affine_element& public_key,
const ecdsa_signature& signature);

/**
* @brief Hash the message and trim the hash output if required
*
* @details Following https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf, if the length of the hash output is
* longer than the bit length of the modulus of the scalar field, we trim the hash output.
*
*/
template <typename Hash, typename Fr> Fr ecdsa_hash_message(const std::string& message);

inline bool operator==(ecdsa_signature const& lhs, ecdsa_signature const& rhs)
{
return lhs.r == rhs.r && lhs.s == rhs.s && lhs.v == rhs.v;
Expand All @@ -55,4 +96,4 @@ inline std::ostream& operator<<(std::ostream& os, ecdsa_signature const& sig)

} // namespace bb::crypto

#include "./ecdsa_impl.hpp"
#include "ecdsa_impl.hpp"
Loading
Loading