Skip to content
Cosmopediaby Unity Nodes
Documentationinformalsystems/auditsinformalsystems/audits › CelestiaView on informalsystems/audits ↗

2023-09-13 Audit Report Celestia rsmt2d library

Security Audit Report

Celestia: Q2 2023

Authors: Ivan Gavran, Andrija Mitrovic

Last revised 13 July, 2023 © 2023 Informal Systems Celestia: Q2 2023

Table of Contents Audit overview............................................................................................................. 1 The Project 1 Conclusions 1 Further Increasing Confidence 1 Disclaimer 1 Audit dashboard.......................................................................................................... 3 Target Summary 3 Engagement Summary 3 Severity Summary 3 System overview ......................................................................................................... 4 Abstract 4 Data Structure 4 Extending data 5 Reconstruction of data 6 Identified Threats and Audit Plan .............................................................................. 8 Threats 8 Audit Plan 8 Findings ....................................................................................................................... 9 ErrByzantineData.Shares are not filled 11 OR instead AND should be used in the test check 13 Check chunk size 14 Position and dimensions of row/column slice is not checked 15 Good coding practice 16 Unnecessary index calculation 17 Code duplication 18 Wrong comment for ErrByzabtineData 19 Good naming practice 20 Unused attribute in test 21 Comments about extending data are wrong 22 Naming of test cases is confusing 23 © 2023 Informal Systems Celestia: Q2 2023

Use ErrUnevenChunks error 24 Unnecessary usage of errors.As instead errors.Is 25 Introduce a new variable for clarity 26 Appendix: Vulnerability Classification ..................................................................... 27 Impact Score 27 Exploitability Score 27 Severity Score 28 © 2023 Informal Systems Celestia: Q2 2023

Audit overview

The Project In June 2023, Informal Systems has conducted a security audit for Celestia of the library rsmt2d. The main focus of the audit was the correctness and functionality of the library and its integration with other repositories of Celestia (celastia-node and celestia-app). The audited commit hash is 6515446b. The audit took place from June 1, 2023 through June 29, 2023 by the following personnel: • Ivan Gavran • Andrija Mitrovic

Conclusions In general, we found the codebase to be of very high quality: the code is well structured and easy to follow, and all functions contain good unit-tests. Repository does not have adequate specs, so those should be added. In the audit, we found 15 issues: most of them informational and one high severity, which was promptly addressed.

Further Increasing Confidence For increasing confidence further, we would suggest enumerating all possible scenarios of the rsmt2d workflow and adding a test for each of them. Those tests go beyond unit tests as they need to include the interplay between different functions. (For instance, a scenario describing the situation in which an encoding error is detected in columns while rebuilding rows would have detected one of the problems found in this audit.)

Disclaimer This report is subject to the terms and conditions (including without limitation, description of services, confidentiality, disclaimer and limitation of liability, etc.) set forth in the associated Services Agreement. This report provided in connection with the Services set forth in the Services Agreement shall be used by the Company only to the extent permitted under the terms and conditions set forth in the Agreement. This audit report is provided on an “as is” basis, with no guarantee of the completeness, accuracy, timeliness or of the results obtained by use of the information provided. Informal has relied upon information and data provided by the client, and is not responsible for any errors or omissions in such information and data or results obtained from the use of that information or conclusions in this report. Informal makes no warranty of any kind, express or implied, regarding the accuracy, adequacy, validity, reliability, availability or completeness of this report. This report should not be considered or utilized as a complete assessment of the overall utility, security or bug free status of the code. This audit report contains confidential information and is only intended for use by the client. Reuse or republication of the audit report other than as authorized by the client is prohibited. This report is not, nor should it be considered, an “endorsement”, “approval” or “disapproval” of any particular project or team. This report is not, nor should it be considered, an indication of the economics or value of any “product” or “asset” created by any team or project that contracts with Informal to perform a security assessment. This report does not provide any warranty or guarantee regarding the absolute bug-free nature of the technology analyzed, nor does it provide any indication of the client’s business, business model or legal compliance. This report should not be used in any way to make decisions around investment or involvement with any particular project. This report in no way provides investment advice, nor should it be leveraged as investment advice of any sort.

Audit overview 1 © 2023 Informal Systems Celestia: Q2 2023

Blockchain technology and cryptographic assets in general and by definition present a high level of ongoing risk. Client is responsible for its own due diligence and continuing security in this regard.

Audit overview 2 © 2023 Informal Systems Celestia: Q2 2023

Audit dashboard Target Summary • Type: Specification and Implementation • Platform: Golang • Artifacts: • rsmt2d

Engagement Summary • Dates: 01.06.2023 to 29.06.2023 • Method: Manual code review, protocol analysis • Employees Engaged: 2

Severity Summary Finding Severity #

Critical 0

High 1

Medium 0

Low 1

Informational 13

Total 15

Audit dashboard 3 © 2023 Informal Systems Celestia: Q2 2023

System overview Abstract Rsmt2d is a library utilized for the erasure coding of data in Celestia. It serves as a specialized package offering functionalities to reorganize data into a square shape, expand it, and apply erasure coding to the original square data. Additionally, it incorporates the capacity to repair or restore incomplete data based on the underlying erasure coding technique. Furthermore, it provides proofs of tampered data, which play a vital role in ensuring data availability within the Celestia platform. The Leopard codec serves as the underlying coding mechanism for Reed-Solomon erasure coding. Originally implemented in the C++ library, Leopard is now utilized by Rsmt2d through a Go port of the C++ library. For shards of 256 or less, the Leopard codec uses an 8-bit implementation, whereas shards exceeding 256 employ a 16-bit version of Leopard.

Data Structure The Rsmt2d library is designed around a squared data structure for efficient data availability workflow. It uses two main structures: dataSquare and extendedDataSquare . The dataSquare structure serves as the foundation and provides the necessary functionality for storing data in a square format. On the other hand, the extendedDataSquare structure inherits from dataSquare and adds extra capabilities to provide necessary functionality for rsmt2d library.

Data Square (DS) As a base data structure used for storing data, a data square is utilized. This data square is implemented by a struct dataSquare which is as follows:

type dataSquare struct { squareRow [][][]byte // row-major squareCol [][][]byte // col-major dataMutex sync.Mutex width uint chunkSize uint rowRoots [][]byte colRoots [][]byte createTreeFn TreeConstructorFn }

DS is a matrix where each cell is a byte array. It contains duplicated data arranged in both row-major and column- major order. This duplication allows for zero-allocation column slices to be provided. It also stores data about the width of the square, chunk size, roots by rows and columns and a delegate to tree constructor that is used for root calculation. All chunks/cells within the data square must be of the same size. The provided functionality of the Data square is as follows:

• Creation of Data Square ( newDataSquare ): Rearranges the given data array into a square and creates a dataSquare object. • Extending Data Square ( extendSquare ): Extends the original square horizontally and vertically by a predefined number of rows/columns and fills it with the same fillerChunk . • Accessing Cells ( GetCell , SetCell , setCell ): Allows reading/writing data from/into cells.

System overview 4 © 2023 Informal Systems Celestia: Q2 2023

• Accessing Row/Column Slices ( rowSlice , row , setRowSlice , colSlice, col, setColSlice ) : Enables reading/writing data from/into row/column slices. • Accessing Roots ( resetRoots , computeRoots , getRowRoots , getRowRoot , getColRoots, getColRoot ): Provides functionality for resetting, computing, and reading row/column roots.

Extended Data Square (EDS) The Extended data square is a data structure that inherits the DS (data square) data type and represents an extended portion of data. Its structure is as follows:

type ExtendedDataSquare struct { *dataSquare codec Codec originalDataWidth uint }

It includes a pointer to the DS struct and introduces additional attributes, codec and originalDataWidth . The codec attribute represents the codec used for encoding/decoding data (as mention, rsmt2d library uses the Leopard codec). The originalDataWidth field is used to store information about the width of the original data square. The provided functionality of the Extended data square is as follows:

• Compute EDS ( ComputeExtendedDataSquare ): This function computes the extended data square for a given set of data chunks. • Import EDS ( ImportExtendedDataSquare ): This function imports an extended data square that is represented as flattened chunks of data. • Gets row/column ( Row , Col ): These functions return a copy of the internal slice, which represents a row or column slice of the extended data square. • Gets row/column roots ( RowRoots , ColRoots ): These functions return the Merkle roots of all the rows or columns within the extended data square.

Extending data Extending data is a part of the Reed Solomon encoding process. The original data square, named Q0, is extended to three more parity data squares: Q1, Q2, and Q3. These squares are filled with encoded original data. The functionality for this process is provided in the function called ComputeExtendedDataSquare .

The process of computing the extended data square with an array of data chunks is as follows (see figure for Erasure extending of the original data square):

  1. Create a new data square ( ds ) from the provided array of data. This serves as the original data square.
  2. Create an extended data square ( eds ) from the created ds in the previous step.
  3. Perform erasure extending on the created eds : a. Extend the original data square to Q1, Q2, and Q3, filling them with empty data chunks. b. Fill Q1 and Q2 with erasure coded data. Q1 is the result of erasure coding Q0 row by row, and Q2 is the result of erasure coding Q0 column by column. c. Fill Q3 with erasure coded data. Q3 is the result of erasure coding Q2 row by row (it will be the same if Q3 is the result of erasure coding Q1 column by column).

System overview 5 © 2023 Informal Systems Celestia: Q2 2023

Note that while the data is laid out in a two-dimensional square, the rows and columns are erasure coded using a standard one-dimensional encoding.

original data parity data

parity data parity data

Erasure extending of original data square

Reconstruction of data The reconstruction of the incomplete extended data square (EDS) is performed in the function Repair. This function continuously compares the repaired rows and columns against the expected Merkle roots. To ensure proper functioning, the missing shares must be set to nil .

The process of repairing is as follows:

  1. A sanity check is performed ( prerepairSanityCheck ), which includes the following checks: a. Verify that the row/column roots from EDS are equal to the expected row/column roots. b. Check if the encoded original data from the row/column is equal to the extended erasure data from EDS.
  2. Iterative solving of crossword ( solveCrossword ).

Solving the crossword involves looping through each row and column in an attempt to rebuild any incomplete rows or columns. This process is repeated until one of the following conditions is met:

  1. The square is solved.
  2. An error is returned from solving rows or columns.
  3. No progress is made. When solving a row/column, if it is completed, a check is performed against the expected Merkle roots (check for rows, check for columns). Additionally, a check for a completed orthogonal column/row is also performed. If the

System overview 6 © 2023 Informal Systems Celestia: Q2 2023

calculated root for a newly completed row/column does not match the expected Merkle root, an ErrByzantineData error is returned.

This error is defined as follows:

type ErrByzantineData struct { Axis Axis // Axis of the data. Index uint // Row/Col index. Shares [][]byte // Pre-repaired shares. Missing shares are nil. }

System overview 7 © 2023 Informal Systems Celestia: Q2 2023

Identified Threats and Audit Plan In this audit of the rsmt2d library, we were looking at the library from two angles:

  1. logic within the library itself
  2. usages of the library functions in the broader Celestia context (be it in celestia-node or celestia- app )

Threats We identified the following threats to the chain stemming from the rsmt2d library:

  1. Wrong usage of the encoding library, resulting in the extended data that does not have the desired recoverability properties.
  2. Problems in the logic for recovering shares from pieces of data. If those problems exist, this would result in full nodes not being able to recover existing data, violating security assumptions of light-nodes.
  3. Problems in sending and validating bad encoding proofs. If this is not done correctly, it could result in a) mistakenly blacklisting an honest peer, or b) accepting a fraudulent bad encoding proof.

Audit Plan We set out to explore the following:

  1. Inspection of how the data square is extended.
  2. Inspection of updates of squareRow and squareCol , two independent variables that are referring to the same data. They have to be updated in sync.
  3. A special attention is given to the function solveCrossword , inspecting termination and correctness of a rebuild process
  4. Review of construction of ErrByzantineData , its transformation into a BadEncodingProof , and its validation in the Validate function.
  5. Making sure that data is never changed without changing the corresponding roots.
  6. Making sure that all assumptions are checked at all relevant places (e.g., chunk size, row/column indices within bounds, etc.)

Identified Threats and Audit Plan 8 © 2023 Informal Systems Celestia: Q2 2023

Findings Title Type Severity Issue

ErrByzantineData.Shares are not filled PROTOCOL 3 HIGH https://github.com/ celestiaorg/rsmt2d/ issues/178

OR instead AND should be used IMPLEMENTATION 1 LOW https://github.com/ in the test check celestiaorg/rsmt2d/ issues/162

Use ErrUnevenChunks error IMPLEMENTATION 0 INFORMATIONAL https://github.com/ celestiaorg/rsmt2d/ issues/163

Unnecessary index calculation IMPLEMENTATION 0 INFORMATIONAL https://github.com/ celestiaorg/rsmt2d/ issues/164

Position and dimensions of row/ IMPLEMENTATION 0 INFORMATIONAL https://github.com/ column slice is not checked celestiaorg/rsmt2d/ issues/169

Check chunk size IMPLEMENTATION 0 INFORMATIONAL https://github.com/ celestiaorg/rsmt2d/ issues/170

Code duplication PRACTICE 0 INFORMATIONAL https://github.com/ celestiaorg/rsmt2d/ issues/171

Wrong comment for ErrByzabtineData DOCUMENTATION 0 INFORMATIONAL https://github.com/ celestiaorg/rsmt2d/ issues/173

Good coding practice PRACTICE 0 INFORMATIONAL https://github.com/ celestiaorg/rsmt2d/ issues/177

Good naming practice PRACTICE 0 INFORMATIONAL https://github.com/ celestiaorg/rsmt2d/ issues/179

Unused attribute in test IMPLEMENTATION 0 INFORMATIONAL https://github.com/ celestiaorg/rsmt2d/ issues/180

Findings 9 © 2023 Informal Systems Celestia: Q2 2023

Title Type Severity Issue

Comments about extending data are DOCUMENTATION 0 INFORMATIONAL https://github.com/ wrong celestiaorg/rsmt2d/ issues/192

Naming of test cases is confusing DOCUMENTATION 0 INFORMATIONAL https://github.com/ celestiaorg/rsmt2d/ issues/194

Unnecessary usage of errors.As IMPLEMENTATION 0 INFORMATIONAL https://github.com/ instead errors.Is celestiaorg/celestia- node/issues/2391

Introduce a new variable for clarity PRACTICE 0 INFORMATIONAL https://github.com/ celestiaorg/celestia- node/issues/2392

Findings 10 © 2023 Informal Systems Celestia: Q2 2023

ErrByzantineData.Shares are not filled Title ErrByzantineData.Shares are not filled

Project Celestia: Q2 2023

Type PROTOCOL

Severity 3 HIGH

Impact 2 MEDIUM

Exploitability 3 HIGH

Issue https://github.com/celestiaorg/rsmt2d/issues/178

Involved artifacts • rsmt2d/extendeddatacrossword.go

Description When ErrByznatineData is raised it is propagated through solveCrossword , Repair , Reconstruct , and Retrieve , where a new ErrByzantine is created. If the ErrByzantineData.Shares field is not filled, GetProofsForShares will return an empty sequence of sharesWithProof , and ErrByzantine is created with that empty sequence sharesWithProof . This is further propagated through GetEDS, SharesAvailable, sample; until a new BadEncodingProof is created, and which will end up propagated (the byzantine error is captured in SharesAvailable) to other nodes. Finally, when such a proof is received by other nodes, they call Validate on it. Since p.Shares is an empty array, an error will be raised upon checking the size of p.Shares , here.

ErrByzantineData.Shares are not set when verification of newly completed orthogonal vectors returns a ErrByzantineData error (first place and second place) that will lead to the previously mentioned flow. On the contrary, these shares are set if a verification of newly completed row or column returns ErrByzantineData error.

Problem Scenarios The byzantine error for data will not be processed properly even if proven. Furthermore, honest peers can get blacklisted.

Findings 11 © 2023 Informal Systems Celestia: Q2 2023

Recommendation Fill in the shares with corresponding column or row data if the verification of that newly completed orthogonal column or row returns an ErrByzantineData .

Status Resolved.

Findings 12 © 2023 Informal Systems Celestia: Q2 2023

OR instead AND should be used in the test check Title OR instead AND should be used in the test check

Project Celestia: Q2 2023

Type IMPLEMENTATION

Severity 1 LOW

Impact 2 MEDIUM

Exploitability 1 LOW

Issue https://github.com/celestiaorg/rsmt2d/issues/162

Involved artifacts • rsmt2d/datasquare_test.go

Description The test TestLazyRootGeneration calculates root by root for each row and column and appends those to local arrays of roots. In the end, it compares these arrays with those that are calculated by extendedDataSquare function computeRoots . Test is supposed to fail if at least one of the root arrays is not equal to the expected value, but the check at the end of the test will lead to failure only if both of root arrays are not equal to the ones from EDS.

Problem Scenarios Test will pass if one of the root arrays does not fit the criteria, but it should fail.

Recommendation At the end of test if statement should check if any of the root arrays has changed and then return an error. Thus or instead of and should be used.

Status Resolved.

Findings 13 © 2023 Informal Systems Celestia: Q2 2023

Check chunk size Title Check chunk size

Project Celestia: Q2 2023

Type IMPLEMENTATION

Severity 0 INFORMATIONAL

Impact 2 MEDIUM

Exploitability 0 NONE

Excerpt (19997 of 37699 characters). Read the whole page on informalsystems/audits ↗