Skip to content

Commit

Permalink
4844: read blobs as raw bytes not as unit256 and fix blob versioned h…
Browse files Browse the repository at this point in the history
…ashes validation (hyperledger#5071)

* Fix: read blobs as raw bytes not as unit256

Signed-off-by: Fabio Di Fabio <fabio.difabio@consensys.net>

* Do not load a trusted setup more than once

Signed-off-by: Fabio Di Fabio <fabio.difabio@consensys.net>

* Update evm/src/main/java/org/hyperledger/besu/evm/precompile/KZGPointEvalPrecompiledContract.java

Co-authored-by: Justin Florentine <justin+github@florentine.us>
Signed-off-by: Fabio Di Fabio <fabio.difabio@consensys.net>

* Ignore tests that fails due to mixing c-kzg presets

Signed-off-by: Fabio Di Fabio <fabio.difabio@consensys.net>

* Revert failing unit test

Signed-off-by: Fabio Di Fabio <fabio.difabio@consensys.net>

---------

Signed-off-by: Fabio Di Fabio <fabio.difabio@consensys.net>
Co-authored-by: Justin Florentine <justin+github@florentine.us>
(cherry picked from commit cd67140)
(cherry picked from commit 25691b172113d4410fe55adc9271aa4a093f419a)
  • Loading branch information
fab-10 authored and jflo committed May 24, 2023
1 parent f9ea8be commit ffb6e96
Show file tree
Hide file tree
Showing 5 changed files with 4,209 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1379,13 +1379,7 @@ public BlobsWithCommitments(

public List<Bytes> getBlobs() {
return blobs.getElements().stream()
.map(
blob -> {
return blob.getElements().stream()
.map(sszuInt256Wrapper -> (Bytes) sszuInt256Wrapper.getData().toBytes())
.reduce(Bytes::concatenate)
.orElseThrow();
})
.map(TransactionNetworkPayload.Blob::getBytes)
.collect(Collectors.toList());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.bytes.Bytes32;
import org.apache.tuweni.ssz.SSZFixedSizeTypeList;
import org.apache.tuweni.ssz.SSZFixedSizeVector;
import org.apache.tuweni.ssz.SSZReadable;
import org.apache.tuweni.ssz.SSZReader;
import org.apache.tuweni.ssz.SSZVariableSizeTypeList;
Expand Down Expand Up @@ -335,8 +334,8 @@ public void setData(final Bytes data) {

public static class AccessTuple implements SSZReadable, SSZWritable {
Bytes address;
SSZFixedSizeTypeList<SSZUInt256Wrapper> storageKeys =
new SSZFixedSizeTypeList<>(ELEMENT_SIZE, SSZUInt256Wrapper::new);
SSZFixedSizeTypeList<SSZByte32Wrapper> storageKeys =
new SSZFixedSizeTypeList<>(ELEMENT_SIZE, SSZByte32Wrapper::new);

@Override
public boolean isFixed() {
Expand All @@ -359,7 +358,7 @@ public Address getAddress() {

public List<Bytes32> getStorageKeys() {
return storageKeys.getElements().stream()
.map(sszuInt256Wrapper -> sszuInt256Wrapper.getData().toBytes())
.map(sszByte32Wrapper -> sszByte32Wrapper.getData())
.collect(Collectors.toList());
}

Expand All @@ -375,9 +374,9 @@ public void setStorageKeys(final List<Bytes32> storageKeys) {
storageKeys.stream()
.map(
bytes32 -> {
SSZUInt256Wrapper sszuInt256Wrapper = new SSZUInt256Wrapper();
sszuInt256Wrapper.setData(UInt256.fromBytes(bytes32));
return sszuInt256Wrapper;
SSZByte32Wrapper sszByte32Wrapper = new SSZByte32Wrapper();
sszByte32Wrapper.setData(UInt256.fromBytes(bytes32));
return sszByte32Wrapper;
})
.collect(Collectors.toList()));
}
Expand Down Expand Up @@ -480,42 +479,41 @@ public Bytes getData() {
}

public static class Blob implements SSZReadable, SSZWritable {
SSZFixedSizeVector<SSZUInt256Wrapper> vector =
new SSZFixedSizeVector<>(FIELD_ELEMENTS_PER_BLOB, ELEMENT_SIZE, SSZUInt256Wrapper::new);
Bytes bytes;

@Override
public void populateFromReader(final SSZReader reader) {
vector.populateFromReader(reader);
bytes = reader.readFixedBytes(FIELD_ELEMENTS_PER_BLOB * ELEMENT_SIZE);
}

@Override
public void writeTo(final SSZWriter writer) {
vector.writeTo(writer);
writer.writeFixedBytes(bytes);
}

public List<SSZUInt256Wrapper> getElements() {
return vector.getElements();
public Bytes getBytes() {
return bytes;
}
}

public static class SSZUInt256Wrapper implements SSZReadable, SSZWritable {
UInt256 data;
public static class SSZByte32Wrapper implements SSZReadable, SSZWritable {
Bytes32 data;

@Override
public void populateFromReader(final SSZReader reader) {
data = reader.readUInt256();
data = Bytes32.wrap(reader.readFixedBytes(32));
}

@Override
public void writeTo(final SSZWriter writer) {
writer.writeUInt256(data);
writer.writeBytes(data);
}

public UInt256 getData() {
public Bytes32 getData() {
return data;
}

public void setData(final UInt256 data) {
public void setData(final Bytes32 data) {
this.data = data;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,8 @@ public ValidationResult<TransactionInvalidReason> validate(
if (!signatureResult.isValid()) {
return signatureResult;
}
if (transaction.getType().equals(TransactionType.BLOB)
&& transaction.getBlobsWithCommitments().isPresent()) {

if (transaction.getType().supportsBlob() && transaction.getBlobsWithCommitments().isPresent()) {
final ValidationResult<TransactionInvalidReason> blobsResult =
validateTransactionsBlobs(transaction);
if (!blobsResult.isValid()) {
Expand Down Expand Up @@ -361,43 +361,49 @@ public ValidationResult<TransactionInvalidReason> validateTransactionsBlobs(
TransactionInvalidReason.INVALID_BLOBS,
"transaction versioned hashes are empty, cannot verify without versioned hashes");
}
List<Hash> versionedHashes = transaction.getVersionedHashes().get();
final List<Hash> versionedHashes = transaction.getVersionedHashes().get();

for (int i = 0; i < versionedHashes.size(); i++) {
TransactionNetworkPayload.KZGCommitment commitment =
final TransactionNetworkPayload.KZGCommitment commitment =
blobsWithCommitments.kzgCommitments.getElements().get(i);
Hash versionedHash = versionedHashes.get(i);
Hash calculatedVersionedHash = hashCommitment(commitment);
final Hash versionedHash = versionedHashes.get(i);

if (versionedHash.get(0) != BLOB_COMMITMENT_VERSION_KZG) {
return ValidationResult.invalid(
TransactionInvalidReason.INVALID_BLOBS,
"transaction blobs commitment version is not supported. Expected "
+ BLOB_COMMITMENT_VERSION_KZG
+ ", found "
+ versionedHash.get(0));
}

final Hash calculatedVersionedHash = hashCommitment(commitment);
if (!calculatedVersionedHash.equals(versionedHash)) {
return ValidationResult.invalid(
TransactionInvalidReason.INVALID_BLOBS,
"transaction blobs commitment hash does not match commitment");
}
}

Bytes blobs =
final Bytes blobs =
blobsWithCommitments.blobs.getElements().stream()
.map(
blob ->
blob.getElements().stream()
.map(sszuInt256Wrapper -> (Bytes) sszuInt256Wrapper.getData().toBytes())
.reduce(Bytes::concatenate)
.orElseThrow())
.map(TransactionNetworkPayload.Blob::getBytes)
.reduce(Bytes::concatenate)
.orElseThrow();

Bytes kzgCommitments =
final Bytes kzgCommitments =
blobsWithCommitments.kzgCommitments.getElements().stream()
.map(commitment -> commitment.getData())
.reduce(Bytes::concatenate)
.orElseThrow();

boolean kzgVerification =
final boolean kzgVerification =
CKZG4844JNI.verifyAggregateKzgProof(
blobs.toArrayUnsafe(),
kzgCommitments.toArrayUnsafe(),
blobsWithCommitments.blobs.getElements().size(),
blobsWithCommitments.kzgProof.getBytes().toArrayUnsafe());

if (!kzgVerification) {
return ValidationResult.invalid(
TransactionInvalidReason.INVALID_BLOBS,
Expand All @@ -408,7 +414,7 @@ public ValidationResult<TransactionInvalidReason> validateTransactionsBlobs(
}

private Hash hashCommitment(final TransactionNetworkPayload.KZGCommitment commitment) {
SHA256Digest digest = new SHA256Digest();
final SHA256Digest digest = new SHA256Digest();
digest.update(commitment.getData().toArrayUnsafe(), 0, commitment.getData().size());

final byte[] dig = new byte[digest.getDigestSize()];
Expand Down
Loading

0 comments on commit ffb6e96

Please sign in to comment.