Skip to content
Open
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
98 changes: 98 additions & 0 deletions ARCs/arc-0081.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
---
arc: 81
title: Participation key integrity hash
description: Integrity checksum identifier for consensus participation keys & key registration transactions
author: Tasos Bitsios (@tasosbit)
discussions-to: https://github.com/algorandfoundation/ARCs/issues/999
status: Final
type: Standards Track
category: Core
created: 2024-12-12
---

## Abstract

This ARC proposes a new identifier for checking the integrity of consensus participation keys, including in the context of key registration transactions.

## Motivation

Participation key material could be corrupted between being generated on a participating node and the wallet where the key registration transaction is signed. Currently, the only way for a node runner to be diligent about signing key registration transactions is to individually verify 176 base64 characters across 3 key fields, as well as the 3 numeric fields for validity and key dilution.

An online keyreg transaction with incorrect partkey material can succeed, which would render the participating account silently delinquent: their registered participation keys would not correspond to the actual keypairs on the node.

The integrity hash aims to be a short, human readable identifier that hashes all relevant participation key material, which node runners can reference at a glance in order to verify the integrity of the participation keys between their node, wallet or later on an explorer.

## Specification
The key words "**MUST**", "**MUST NOT**", "**REQUIRED**", "**SHALL**", "**SHALL NOT**", "**SHOULD**", "**SHOULD NOT**", "**RECOMMENDED**", "**MAY**", and "**OPTIONAL**" in this document are to be interpreted as described in <a href="https://www.ietf.org/rfc/rfc2119.txt">RFC-2119</a>.

The integrity hash is a shortened version of a SHA512_256 hash of the concatenated part key material, represented in base32 encoding:

Formula: `base32_nopad(substr(sha512_256(concat_key_material), 0, 8))`

Where:

- `concat_key_material` uniquely identifies the participation key in the context of a key registration transaction:
- it is a concatenation of the following values:
- network genesis hash (raw encoding, length: 32 bytes)
- account address (raw encoding, length: 32 bytes)
- selection key (raw encoding, length: 32 bytes)
- vote key (raw encoding, length: 32 bytes)
- state proof key (raw encoding, length: 64 bytes)
- first valid voting round (encoded as uint64, length: 8 bytes)
- Note: this MUST NOT be omitted. When the first valid voting round is zero, an explicit uint64 zero value is expected.
- Implementation warning: this field can be missing in msgpack encoded keyreg transactions due to the `omitempty` behavior.
- last valid voting round (encoded as uint64, length: 8 bytes)
- key dilution (encoded as uint64, length: 8 bytes)
- its length MUST be exactly 216 bytes
- `sha512_256` refers to the SHA512_256 hashing function
- `substr(x, 0, 8)` refers to the "substring" function, i.e. returning the first 8 bytes of value `x`
- `base32_nopad` refers to the RFC 4648 base32 encoding function, without padding characters

For offline key registration transactions, the integrity hash MUST be calculated with zeroed values for the key material fields. The length of the concatenared key material MUST be 216 bytes, the same as the online key registration hashes. The fields requiring non-zero values for an offline participation key integrity hash are: genesis hash, account address.

## Rationale

- The key material to be hashed was chosen to uniquely identify the participation key.
- SHA512_256 was chosen for its widespread availability alongside Algorand SDKs.
- A truncated hash was chosen over using the full 32 bytes in order to improve the experience of comparing a hash exhaustively. In base32, 8 bytes encode to a 13-character string, vs. 32 bytes encoding to 52 characters.
- This choice was made while acknowledging that truncating the hash weakens its cryptographic strength significantly. This identifier is meant to be used as an error-detection checksum, not a cryptographically strong guarantee.
- The network genesis hash is included to prevent signing for a set of participation keys intended for a different network. Technically, participation keys are not tied to a specific network, but practically tranferring participation keys across networks should be exceedingly rare.
- The offline scenario is supported to disambiguate offline key registrations between networks.

## Test Cases

### Online keys integrity hash

Arguments:

- Genesis Hash: kUt08LxeVAAGHnh4JoAoAMM9ql/hBwSoiFtlnKNeOxA=
- Account: OHQTAISSIGRGIGVN6TVJ6WYLBHFTUC437T4E2LRRXGWVNJ4GSZOXKPH7N4
- Selection Key: e4kBLu7zXOorjLVzJHOiAn+IhOBsYBCqqHKaJCiCdJs=
- Vote Key: WWHePYtNZ2T3sHkqdd/38EvoFWrnIKPrTo6xN/4T1l4=
- State Proof Key: 1GdNPOck+t6yXvuXxrDEPKqgi4I2sTaNugV1kd5ksUW2G1U6x1FT0WR3aT3ZSSmbYoDt3cVrB3vIPJA8GkqSYg==
- Vote First Valid: 3118965
- Vote Last Valid: 4104516
- Key Dilution: 993

Resulting integrity hash: 2P4RW3CRB7VKA

### Offline keys integrity hash

Arguments:

- Genesis Hash: kUt08LxeVAAGHnh4JoAoAMM9ql/hBwSoiFtlnKNeOxA=
- Account: OHQTAISSIGRGIGVN6TVJ6WYLBHFTUC437T4E2LRRXGWVNJ4GSZOXKPH7N4

Resulting integrity hash: W5TM4AVRNRJIC

## Reference Implementation

A reference implementation in Typescript is provided [here](../assets/arc-0081/src/index.ts).

## Security Considerations

The hash truncation involved in generating the integrity hash sacrifices cryptographic strength for ease of verification. It should not be considered a cryptographically strong identifier, but an error-detection checksum method.

## Copyright

Copyright and related rights waived via <a href="https://creativecommons.org/publicdomain/zero/1.0/">CCO</a>.
2 changes: 2 additions & 0 deletions assets/arc-0081/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
dist/
node_modules/
21 changes: 21 additions & 0 deletions assets/arc-0081/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# ARC-81 Reference Implementation

"Participation key integrity hash" reference implementation in Typescript

Source under `src/index.ts`

## Setup & Build

```bash
npm install
npm run build
```

Built files will be in `dist/`

## Run Tests

```
npm run test
```

7 changes: 7 additions & 0 deletions assets/arc-0081/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/** @type {import('ts-jest').JestConfigWithTsJest} **/
export default {
testEnvironment: "node",
transform: {
"^.+.tsx?$": ["ts-jest",{}],
},
};
Loading
Loading