From f06d9c400e9bb98d039be70a6044f2e4f487fa59 Mon Sep 17 00:00:00 2001 From: Dmitrii Shmatko Date: Thu, 10 Nov 2022 20:28:16 +0400 Subject: [PATCH 1/2] Add Blob, KZGProof, KZGCommitment with SSZ containers --- ethereum/spec/build.gradle | 2 + .../teku/spec/config/SpecConfigEip4844.java | 1 + .../spec/datastructures/blocks/blob/Blob.java | 29 +++++ .../blocks/blob/BlobSchema.java | 35 ++++++ .../datastructures/type/SszKZGCommitment.java | 59 ++++++++++ .../type/SszKZGCommitmentSchema.java | 40 +++++++ .../spec/datastructures/type/SszKZGProof.java | 59 ++++++++++ .../type/SszKZGProofSchema.java | 40 +++++++ .../type/SszKZGCommitmentPropertyTest.java | 37 ++++++ .../type/SszKZGCommitmentSupplier.java | 23 ++++ .../type/SszKZGProofPropertyTest.java | 36 ++++++ .../type/SszKZGProofSupplier.java | 23 ++++ .../teku/spec/util/DataStructureUtil.java | 25 ++++ infrastructure/kzg/build.gradle | 5 + .../tech/pegasys/teku/kzg/KZGCommitment.java | 109 ++++++++++++++++++ .../java/tech/pegasys/teku/kzg/KZGProof.java | 107 +++++++++++++++++ settings.gradle | 1 + 17 files changed, 631 insertions(+) create mode 100644 ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blob/Blob.java create mode 100644 ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blob/BlobSchema.java create mode 100644 ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/type/SszKZGCommitment.java create mode 100644 ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/type/SszKZGCommitmentSchema.java create mode 100644 ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/type/SszKZGProof.java create mode 100644 ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/type/SszKZGProofSchema.java create mode 100644 ethereum/spec/src/property-test/java/tech/pegasys/teku/spec/datastructures/type/SszKZGCommitmentPropertyTest.java create mode 100644 ethereum/spec/src/property-test/java/tech/pegasys/teku/spec/datastructures/type/SszKZGCommitmentSupplier.java create mode 100644 ethereum/spec/src/property-test/java/tech/pegasys/teku/spec/datastructures/type/SszKZGProofPropertyTest.java create mode 100644 ethereum/spec/src/property-test/java/tech/pegasys/teku/spec/datastructures/type/SszKZGProofSupplier.java create mode 100644 infrastructure/kzg/build.gradle create mode 100644 infrastructure/kzg/src/main/java/tech/pegasys/teku/kzg/KZGCommitment.java create mode 100644 infrastructure/kzg/src/main/java/tech/pegasys/teku/kzg/KZGProof.java diff --git a/ethereum/spec/build.gradle b/ethereum/spec/build.gradle index 02b4e313886..b78325bfc3c 100644 --- a/ethereum/spec/build.gradle +++ b/ethereum/spec/build.gradle @@ -22,6 +22,7 @@ dependencies { implementation project(':infrastructure:events') implementation project(':infrastructure:exceptions') implementation project(':infrastructure:io') + implementation project(':infrastructure:kzg') implementation project(':infrastructure:logging') implementation project(':infrastructure:ssz') implementation project(':infrastructure:time') @@ -45,6 +46,7 @@ dependencies { testFixturesImplementation project(':infrastructure:crypto') testFixturesImplementation project(':infrastructure:events') testFixturesImplementation project(':infrastructure:io') + testFixturesImplementation project(':infrastructure:kzg') testFixturesImplementation project(':infrastructure:time') testFixturesImplementation project(':infrastructure:unsigned') testFixturesImplementation testFixtures(project(':infrastructure:async')) diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/config/SpecConfigEip4844.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/config/SpecConfigEip4844.java index 00d9d9ca638..5382875d713 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/config/SpecConfigEip4844.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/config/SpecConfigEip4844.java @@ -21,6 +21,7 @@ public interface SpecConfigEip4844 extends SpecConfigCapella { Bytes BLOB_TX_TYPE = Bytes.fromHexString("0x05"); Bytes VERSIONED_HASH_VERSION_KZG = Bytes.fromHexString("0x01"); + UInt64 BYTES_PER_FIELD_ELEMENT = UInt64.valueOf(32); static SpecConfigEip4844 required(final SpecConfig specConfig) { return specConfig diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blob/Blob.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blob/Blob.java new file mode 100644 index 00000000000..80ea8ae4ca8 --- /dev/null +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blob/Blob.java @@ -0,0 +1,29 @@ +/* + * Copyright ConsenSys Software Inc., 2022 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package tech.pegasys.teku.spec.datastructures.blocks.blob; + +import tech.pegasys.teku.infrastructure.ssz.collections.impl.SszByteVectorImpl; +import tech.pegasys.teku.infrastructure.ssz.tree.TreeNode; + +public class Blob extends SszByteVectorImpl { + + Blob(BlobSchema schema, TreeNode backingNode) { + super(schema, backingNode); + } + + @Override + public BlobSchema getSchema() { + return (BlobSchema) super.getSchema(); + } +} diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blob/BlobSchema.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blob/BlobSchema.java new file mode 100644 index 00000000000..7a1ae869c30 --- /dev/null +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blob/BlobSchema.java @@ -0,0 +1,35 @@ +/* + * Copyright ConsenSys Software Inc., 2022 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package tech.pegasys.teku.spec.datastructures.blocks.blob; + +import tech.pegasys.teku.infrastructure.ssz.schema.SszPrimitiveSchemas; +import tech.pegasys.teku.infrastructure.ssz.schema.collections.impl.SszByteVectorSchemaImpl; +import tech.pegasys.teku.infrastructure.ssz.tree.TreeNode; +import tech.pegasys.teku.spec.config.SpecConfigEip4844; + +public class BlobSchema extends SszByteVectorSchemaImpl { + + public BlobSchema(final SpecConfigEip4844 specConfig) { + super( + SszPrimitiveSchemas.BYTE_SCHEMA, + SpecConfigEip4844.BYTES_PER_FIELD_ELEMENT + .times(specConfig.getFieldElementsPerBlob()) + .longValue()); + } + + @Override + public Blob createFromBackingNode(TreeNode node) { + return new Blob(this, node); + } +} diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/type/SszKZGCommitment.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/type/SszKZGCommitment.java new file mode 100644 index 00000000000..db5980ad2da --- /dev/null +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/type/SszKZGCommitment.java @@ -0,0 +1,59 @@ +/* + * Copyright ConsenSys Software Inc., 2022 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package tech.pegasys.teku.spec.datastructures.type; + +import com.google.common.base.Suppliers; +import java.util.function.Supplier; +import org.apache.tuweni.bytes.Bytes48; +import tech.pegasys.teku.infrastructure.ssz.collections.impl.SszByteVectorImpl; +import tech.pegasys.teku.infrastructure.ssz.tree.TreeNode; +import tech.pegasys.teku.kzg.KZGCommitment; + +public class SszKZGCommitment extends SszByteVectorImpl { + + private final Supplier kzgCommitment; + + public SszKZGCommitment(final Bytes48 kzgCommitmentBytes) { + super(SszKZGCommitmentSchema.INSTANCE, kzgCommitmentBytes); + this.kzgCommitment = Suppliers.memoize(this::createKZGCommitment); + } + + public SszKZGCommitment(final KZGCommitment kzgCommitment) { + super(SszKZGCommitmentSchema.INSTANCE, kzgCommitment.getBytesCompressed()); + this.kzgCommitment = Suppliers.memoize(this::createKZGCommitment); + } + + SszKZGCommitment(final TreeNode backingNode) { + super(SszKZGCommitmentSchema.INSTANCE, backingNode); + this.kzgCommitment = Suppliers.memoize(this::createKZGCommitment); + } + + public KZGCommitment getKZGCommitment() { + return kzgCommitment.get(); + } + + private KZGCommitment createKZGCommitment() { + return KZGCommitment.fromBytesCompressed(getBytes()); + } + + @Override + public Bytes48 getBytes() { + return Bytes48.wrap(super.getBytes()); + } + + @Override + public SszKZGCommitmentSchema getSchema() { + return (SszKZGCommitmentSchema) super.getSchema(); + } +} diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/type/SszKZGCommitmentSchema.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/type/SszKZGCommitmentSchema.java new file mode 100644 index 00000000000..d9addcb539b --- /dev/null +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/type/SszKZGCommitmentSchema.java @@ -0,0 +1,40 @@ +/* + * Copyright ConsenSys Software Inc., 2022 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package tech.pegasys.teku.spec.datastructures.type; + +import tech.pegasys.teku.infrastructure.json.types.DeserializableTypeDefinition; +import tech.pegasys.teku.infrastructure.ssz.schema.SszPrimitiveSchemas; +import tech.pegasys.teku.infrastructure.ssz.schema.collections.impl.SszByteVectorSchemaImpl; +import tech.pegasys.teku.infrastructure.ssz.schema.json.SszPrimitiveTypeDefinitions; +import tech.pegasys.teku.infrastructure.ssz.tree.TreeNode; + +public class SszKZGCommitmentSchema extends SszByteVectorSchemaImpl { + private static final int KZG_COMMITMENT_SIZE = 48; + + public static final SszKZGCommitmentSchema INSTANCE = new SszKZGCommitmentSchema(); + + private SszKZGCommitmentSchema() { + super(SszPrimitiveSchemas.BYTE_SCHEMA, KZG_COMMITMENT_SIZE); + } + + @Override + protected DeserializableTypeDefinition createTypeDefinition() { + return SszPrimitiveTypeDefinitions.sszSerializedType(this, "Bytes48 hexadecimal"); + } + + @Override + public SszKZGCommitment createFromBackingNode(final TreeNode node) { + return new SszKZGCommitment(node); + } +} diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/type/SszKZGProof.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/type/SszKZGProof.java new file mode 100644 index 00000000000..d58401bf77a --- /dev/null +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/type/SszKZGProof.java @@ -0,0 +1,59 @@ +/* + * Copyright ConsenSys Software Inc., 2022 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package tech.pegasys.teku.spec.datastructures.type; + +import com.google.common.base.Suppliers; +import java.util.function.Supplier; +import org.apache.tuweni.bytes.Bytes48; +import tech.pegasys.teku.infrastructure.ssz.collections.impl.SszByteVectorImpl; +import tech.pegasys.teku.infrastructure.ssz.tree.TreeNode; +import tech.pegasys.teku.kzg.KZGProof; + +public class SszKZGProof extends SszByteVectorImpl { + + private final Supplier kzgProof; + + public SszKZGProof(final Bytes48 kzgProofBytes) { + super(SszKZGProofSchema.INSTANCE, kzgProofBytes); + this.kzgProof = Suppliers.memoize(this::createKZGProof); + } + + public SszKZGProof(final KZGProof kzgProof) { + super(SszKZGProofSchema.INSTANCE, kzgProof.getBytesCompressed()); + this.kzgProof = Suppliers.memoize(this::createKZGProof); + } + + SszKZGProof(final TreeNode backingNode) { + super(SszKZGProofSchema.INSTANCE, backingNode); + this.kzgProof = Suppliers.memoize(this::createKZGProof); + } + + public KZGProof getKZGProof() { + return kzgProof.get(); + } + + private KZGProof createKZGProof() { + return KZGProof.fromBytesCompressed(getBytes()); + } + + @Override + public Bytes48 getBytes() { + return Bytes48.wrap(super.getBytes()); + } + + @Override + public SszKZGProofSchema getSchema() { + return (SszKZGProofSchema) super.getSchema(); + } +} diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/type/SszKZGProofSchema.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/type/SszKZGProofSchema.java new file mode 100644 index 00000000000..d9876f9b464 --- /dev/null +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/type/SszKZGProofSchema.java @@ -0,0 +1,40 @@ +/* + * Copyright ConsenSys Software Inc., 2022 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package tech.pegasys.teku.spec.datastructures.type; + +import tech.pegasys.teku.infrastructure.json.types.DeserializableTypeDefinition; +import tech.pegasys.teku.infrastructure.ssz.schema.SszPrimitiveSchemas; +import tech.pegasys.teku.infrastructure.ssz.schema.collections.impl.SszByteVectorSchemaImpl; +import tech.pegasys.teku.infrastructure.ssz.schema.json.SszPrimitiveTypeDefinitions; +import tech.pegasys.teku.infrastructure.ssz.tree.TreeNode; + +public class SszKZGProofSchema extends SszByteVectorSchemaImpl { + private static final int KZG_PROOF_SIZE = 48; + + public static final SszKZGProofSchema INSTANCE = new SszKZGProofSchema(); + + private SszKZGProofSchema() { + super(SszPrimitiveSchemas.BYTE_SCHEMA, KZG_PROOF_SIZE); + } + + @Override + protected DeserializableTypeDefinition createTypeDefinition() { + return SszPrimitiveTypeDefinitions.sszSerializedType(this, "Bytes48 hexadecimal"); + } + + @Override + public SszKZGProof createFromBackingNode(final TreeNode node) { + return new SszKZGProof(node); + } +} diff --git a/ethereum/spec/src/property-test/java/tech/pegasys/teku/spec/datastructures/type/SszKZGCommitmentPropertyTest.java b/ethereum/spec/src/property-test/java/tech/pegasys/teku/spec/datastructures/type/SszKZGCommitmentPropertyTest.java new file mode 100644 index 00000000000..32d92e818bc --- /dev/null +++ b/ethereum/spec/src/property-test/java/tech/pegasys/teku/spec/datastructures/type/SszKZGCommitmentPropertyTest.java @@ -0,0 +1,37 @@ +/* + * Copyright ConsenSys Software Inc., 2022 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package tech.pegasys.teku.spec.datastructures.type; + +import static tech.pegasys.teku.spec.datastructures.util.PropertyTestHelper.assertDeserializeMutatedThrowsExpected; +import static tech.pegasys.teku.spec.datastructures.util.PropertyTestHelper.assertRoundTrip; + +import com.fasterxml.jackson.core.JsonProcessingException; +import net.jqwik.api.ForAll; +import net.jqwik.api.Property; + +public class SszKZGCommitmentPropertyTest { + @Property + void roundTrip( + @ForAll(supplier = SszKZGCommitmentSupplier.class) final SszKZGCommitment sszKZGCommitment) + throws JsonProcessingException { + assertRoundTrip(sszKZGCommitment); + } + + @Property + void deserializeMutated( + @ForAll(supplier = SszKZGCommitmentSupplier.class) final SszKZGCommitment sszKZGCommitment, + @ForAll final int seed) { + assertDeserializeMutatedThrowsExpected(sszKZGCommitment, seed); + } +} diff --git a/ethereum/spec/src/property-test/java/tech/pegasys/teku/spec/datastructures/type/SszKZGCommitmentSupplier.java b/ethereum/spec/src/property-test/java/tech/pegasys/teku/spec/datastructures/type/SszKZGCommitmentSupplier.java new file mode 100644 index 00000000000..e7845321f96 --- /dev/null +++ b/ethereum/spec/src/property-test/java/tech/pegasys/teku/spec/datastructures/type/SszKZGCommitmentSupplier.java @@ -0,0 +1,23 @@ +/* + * Copyright ConsenSys Software Inc., 2022 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package tech.pegasys.teku.spec.datastructures.type; + +import tech.pegasys.teku.spec.propertytest.suppliers.DataStructureUtilSupplier; +import tech.pegasys.teku.spec.util.DataStructureUtil; + +public class SszKZGCommitmentSupplier extends DataStructureUtilSupplier { + public SszKZGCommitmentSupplier() { + super(DataStructureUtil::randomSszKZGCommitment); + } +} diff --git a/ethereum/spec/src/property-test/java/tech/pegasys/teku/spec/datastructures/type/SszKZGProofPropertyTest.java b/ethereum/spec/src/property-test/java/tech/pegasys/teku/spec/datastructures/type/SszKZGProofPropertyTest.java new file mode 100644 index 00000000000..baba6745b31 --- /dev/null +++ b/ethereum/spec/src/property-test/java/tech/pegasys/teku/spec/datastructures/type/SszKZGProofPropertyTest.java @@ -0,0 +1,36 @@ +/* + * Copyright ConsenSys Software Inc., 2022 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package tech.pegasys.teku.spec.datastructures.type; + +import static tech.pegasys.teku.spec.datastructures.util.PropertyTestHelper.assertDeserializeMutatedThrowsExpected; +import static tech.pegasys.teku.spec.datastructures.util.PropertyTestHelper.assertRoundTrip; + +import com.fasterxml.jackson.core.JsonProcessingException; +import net.jqwik.api.ForAll; +import net.jqwik.api.Property; + +public class SszKZGProofPropertyTest { + @Property + void roundTrip(@ForAll(supplier = SszKZGProofSupplier.class) final SszKZGProof sszKZGProof) + throws JsonProcessingException { + assertRoundTrip(sszKZGProof); + } + + @Property + void deserializeMutated( + @ForAll(supplier = SszKZGProofSupplier.class) final SszKZGProof sszKZGProof, + @ForAll final int seed) { + assertDeserializeMutatedThrowsExpected(sszKZGProof, seed); + } +} diff --git a/ethereum/spec/src/property-test/java/tech/pegasys/teku/spec/datastructures/type/SszKZGProofSupplier.java b/ethereum/spec/src/property-test/java/tech/pegasys/teku/spec/datastructures/type/SszKZGProofSupplier.java new file mode 100644 index 00000000000..dcf2b1a449b --- /dev/null +++ b/ethereum/spec/src/property-test/java/tech/pegasys/teku/spec/datastructures/type/SszKZGProofSupplier.java @@ -0,0 +1,23 @@ +/* + * Copyright ConsenSys Software Inc., 2022 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package tech.pegasys.teku.spec.datastructures.type; + +import tech.pegasys.teku.spec.propertytest.suppliers.DataStructureUtilSupplier; +import tech.pegasys.teku.spec.util.DataStructureUtil; + +public class SszKZGProofSupplier extends DataStructureUtilSupplier { + public SszKZGProofSupplier() { + super(DataStructureUtil::randomSszKZGProof); + } +} diff --git a/ethereum/spec/src/testFixtures/java/tech/pegasys/teku/spec/util/DataStructureUtil.java b/ethereum/spec/src/testFixtures/java/tech/pegasys/teku/spec/util/DataStructureUtil.java index 63b7e0dbd9f..64e23cff6a2 100644 --- a/ethereum/spec/src/testFixtures/java/tech/pegasys/teku/spec/util/DataStructureUtil.java +++ b/ethereum/spec/src/testFixtures/java/tech/pegasys/teku/spec/util/DataStructureUtil.java @@ -69,6 +69,8 @@ import tech.pegasys.teku.infrastructure.ssz.schema.collections.SszPrimitiveVectorSchema; import tech.pegasys.teku.infrastructure.ssz.schema.collections.SszUInt64ListSchema; import tech.pegasys.teku.infrastructure.unsigned.UInt64; +import tech.pegasys.teku.kzg.KZGCommitment; +import tech.pegasys.teku.kzg.KZGProof; import tech.pegasys.teku.spec.Spec; import tech.pegasys.teku.spec.SpecMilestone; import tech.pegasys.teku.spec.SpecVersion; @@ -138,6 +140,8 @@ import tech.pegasys.teku.spec.datastructures.state.beaconstate.MutableBeaconState; import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.altair.BeaconStateSchemaAltair; import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.phase0.BeaconStateSchemaPhase0; +import tech.pegasys.teku.spec.datastructures.type.SszKZGCommitment; +import tech.pegasys.teku.spec.datastructures.type.SszKZGProof; import tech.pegasys.teku.spec.datastructures.type.SszPublicKey; import tech.pegasys.teku.spec.datastructures.type.SszSignature; import tech.pegasys.teku.spec.datastructures.util.DepositGenerator; @@ -229,6 +233,11 @@ public Bytes32 randomBytes32() { return Bytes32.random(random); } + public Bytes48 randomBytes48() { + final Random random = new Random(nextSeed()); + return Bytes48.random(random); + } + public Bytes8 randomBytes8() { return new Bytes8(randomBytes32().slice(0, 8)); } @@ -349,6 +358,22 @@ public SszPublicKey randomSszPublicKey() { return new SszPublicKey(randomPublicKey()); } + public KZGCommitment randomKZGCommitment() { + return KZGCommitment.fromBytesCompressed(randomBytes48()); + } + + public SszKZGCommitment randomSszKZGCommitment() { + return new SszKZGCommitment(randomKZGCommitment()); + } + + public KZGProof randomKZGProof() { + return KZGProof.fromBytesCompressed(randomBytes48()); + } + + public SszKZGProof randomSszKZGProof() { + return new SszKZGProof(randomKZGProof()); + } + public Bytes48 randomPublicKeyBytes() { return pubKeyGenerator.get().toBytesCompressed(); } diff --git a/infrastructure/kzg/build.gradle b/infrastructure/kzg/build.gradle new file mode 100644 index 00000000000..af31f78b405 --- /dev/null +++ b/infrastructure/kzg/build.gradle @@ -0,0 +1,5 @@ +dependencies { + implementation 'org.apache.tuweni:tuweni-bytes' + implementation 'org.apache.tuweni:tuweni-ssz' + implementation 'commons-io:commons-io' +} diff --git a/infrastructure/kzg/src/main/java/tech/pegasys/teku/kzg/KZGCommitment.java b/infrastructure/kzg/src/main/java/tech/pegasys/teku/kzg/KZGCommitment.java new file mode 100644 index 00000000000..a1c41568712 --- /dev/null +++ b/infrastructure/kzg/src/main/java/tech/pegasys/teku/kzg/KZGCommitment.java @@ -0,0 +1,109 @@ +/* + * Copyright ConsenSys Software Inc., 2022 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package tech.pegasys.teku.kzg; + +import static com.google.common.base.Preconditions.checkArgument; + +import java.util.Objects; +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes48; +import org.apache.tuweni.ssz.SSZ; + +public final class KZGCommitment { + + public static final int KZG_COMMITMENT_SIZE = 48; + + /** + * Creates 0x00..00 for point-at-infinity + * + * @return point-at-infinity as per the Eth2 spec + */ + public static KZGCommitment infinity() { + return KZGCommitment.fromBytesCompressed(Bytes48.ZERO); + } + + public static KZGCommitment fromHexString(final String hexString) { + return KZGCommitment.fromBytesCompressed(Bytes48.fromHexString(hexString)); + } + + public static KZGCommitment fromSSZBytes(final Bytes bytes) { + checkArgument( + bytes.size() == KZG_COMMITMENT_SIZE, + "Expected " + KZG_COMMITMENT_SIZE + " bytes but received %s.", + bytes.size()); + return SSZ.decode( + bytes, + reader -> new KZGCommitment(Bytes48.wrap(reader.readFixedBytes(KZG_COMMITMENT_SIZE)))); + } + + public static KZGCommitment fromBytesCompressed(final Bytes48 bytes) + throws IllegalArgumentException { + return new KZGCommitment(bytes); + } + + private final Bytes48 bytesCompressed; + + public KZGCommitment(final Bytes48 bytesCompressed) { + this.bytesCompressed = bytesCompressed; + } + + /** + * Returns the SSZ serialization of the compressed form of the commitment + * + * @return the serialization of the compressed form of the commitment. + */ + public Bytes toSSZBytes() { + return SSZ.encode(writer -> writer.writeFixedBytes(getBytesCompressed())); + } + + public Bytes48 getBytesCompressed() { + return bytesCompressed; + } + + public String toAbbreviatedString() { + return getBytesCompressed().toUnprefixedHexString().substring(0, 7); + } + + public String toHexString() { + return getBytesCompressed().toHexString(); + } + + @Override + public String toString() { + return getBytesCompressed().toString(); + } + + @Override + public boolean equals(final Object obj) { + if (Objects.isNull(obj)) { + return false; + } + + if (this == obj) { + return true; + } + + if (!(obj instanceof KZGCommitment)) { + return false; + } + + KZGCommitment other = (KZGCommitment) obj; + return Objects.equals(this.getBytesCompressed(), other.getBytesCompressed()); + } + + @Override + public int hashCode() { + return Objects.hash(getBytesCompressed()); + } +} diff --git a/infrastructure/kzg/src/main/java/tech/pegasys/teku/kzg/KZGProof.java b/infrastructure/kzg/src/main/java/tech/pegasys/teku/kzg/KZGProof.java new file mode 100644 index 00000000000..1683acb269d --- /dev/null +++ b/infrastructure/kzg/src/main/java/tech/pegasys/teku/kzg/KZGProof.java @@ -0,0 +1,107 @@ +/* + * Copyright ConsenSys Software Inc., 2022 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package tech.pegasys.teku.kzg; + +import static com.google.common.base.Preconditions.checkArgument; + +import java.util.Objects; +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes48; +import org.apache.tuweni.ssz.SSZ; + +public final class KZGProof { + + public static final int KZG_PROOF_SIZE = 48; + + /** + * Creates 0x00..00 for point-at-infinity + * + * @return point-at-infinity as per the Eth2 spec + */ + public static KZGProof infinity() { + return KZGProof.fromBytesCompressed(Bytes48.ZERO); + } + + public static KZGProof fromHexString(final String hexString) { + return KZGProof.fromBytesCompressed(Bytes48.fromHexString(hexString)); + } + + public static KZGProof fromSSZBytes(final Bytes bytes) { + checkArgument( + bytes.size() == KZG_PROOF_SIZE, + "Expected " + KZG_PROOF_SIZE + " bytes but received %s.", + bytes.size()); + return SSZ.decode( + bytes, reader -> new KZGProof(Bytes48.wrap(reader.readFixedBytes(KZG_PROOF_SIZE)))); + } + + public static KZGProof fromBytesCompressed(final Bytes48 bytes) throws IllegalArgumentException { + return new KZGProof(bytes); + } + + private final Bytes48 bytesCompressed; + + public KZGProof(final Bytes48 bytesCompressed) { + this.bytesCompressed = bytesCompressed; + } + + /** + * Returns the SSZ serialization of the compressed form of the commitment + * + * @return the serialization of the compressed form of the commitment. + */ + public Bytes toSSZBytes() { + return SSZ.encode(writer -> writer.writeFixedBytes(getBytesCompressed())); + } + + public Bytes48 getBytesCompressed() { + return bytesCompressed; + } + + public String toAbbreviatedString() { + return getBytesCompressed().toUnprefixedHexString().substring(0, 7); + } + + public String toHexString() { + return getBytesCompressed().toHexString(); + } + + @Override + public String toString() { + return getBytesCompressed().toString(); + } + + @Override + public boolean equals(final Object obj) { + if (Objects.isNull(obj)) { + return false; + } + + if (this == obj) { + return true; + } + + if (!(obj instanceof KZGProof)) { + return false; + } + + KZGProof other = (KZGProof) obj; + return Objects.equals(this.getBytesCompressed(), other.getBytesCompressed()); + } + + @Override + public int hashCode() { + return Objects.hash(getBytesCompressed()); + } +} diff --git a/settings.gradle b/settings.gradle index 391a31b6805..c440a60a69b 100644 --- a/settings.gradle +++ b/settings.gradle @@ -35,6 +35,7 @@ include 'infrastructure:http' include 'infrastructure:io' include 'infrastructure:jackson' include 'infrastructure:json' +include 'infrastructure:kzg' include 'infrastructure:metrics' include 'infrastructure:unsigned' include 'infrastructure:logging' From f1e88689bc08418514ae3535e9ad23aa20292929 Mon Sep 17 00:00:00 2001 From: Dmitrii Shmatko Date: Thu, 10 Nov 2022 21:48:51 +0400 Subject: [PATCH 2/2] Move Blob to execution datastructures --- .../{blocks/blob => execution/versions/eip4844}/Blob.java | 2 +- .../{blocks/blob => execution/versions/eip4844}/BlobSchema.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/{blocks/blob => execution/versions/eip4844}/Blob.java (92%) rename ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/{blocks/blob => execution/versions/eip4844}/BlobSchema.java (94%) diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blob/Blob.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/versions/eip4844/Blob.java similarity index 92% rename from ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blob/Blob.java rename to ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/versions/eip4844/Blob.java index 80ea8ae4ca8..e3158272a34 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blob/Blob.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/versions/eip4844/Blob.java @@ -11,7 +11,7 @@ * specific language governing permissions and limitations under the License. */ -package tech.pegasys.teku.spec.datastructures.blocks.blob; +package tech.pegasys.teku.spec.datastructures.execution.versions.eip4844; import tech.pegasys.teku.infrastructure.ssz.collections.impl.SszByteVectorImpl; import tech.pegasys.teku.infrastructure.ssz.tree.TreeNode; diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blob/BlobSchema.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/versions/eip4844/BlobSchema.java similarity index 94% rename from ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blob/BlobSchema.java rename to ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/versions/eip4844/BlobSchema.java index 7a1ae869c30..3657adce546 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/blocks/blob/BlobSchema.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/versions/eip4844/BlobSchema.java @@ -11,7 +11,7 @@ * specific language governing permissions and limitations under the License. */ -package tech.pegasys.teku.spec.datastructures.blocks.blob; +package tech.pegasys.teku.spec.datastructures.execution.versions.eip4844; import tech.pegasys.teku.infrastructure.ssz.schema.SszPrimitiveSchemas; import tech.pegasys.teku.infrastructure.ssz.schema.collections.impl.SszByteVectorSchemaImpl;