Skip to content
This repository has been archived by the owner on Sep 26, 2019. It is now read-only.

Commit

Permalink
[PIE-1706] Properly validate AltBN128 pairing precompile input (#1600)
Browse files Browse the repository at this point in the history
  • Loading branch information
mbaxter authored Jun 25, 2019
1 parent 09f0a41 commit 333135b
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ private static Fq[] polyRoundedDiv(final Fq[] a, final Fq[] b) {

private static int deg(final Fq[] p) {
int d = p.length - 1;
while (p[d].equals(Fq.zero()) && d >= 0) {
while (d >= 0 && p[d].equals(Fq.zero())) {
--d;
}
return d;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
* https://github.com/ethereum/py_ecc/blob/master/py_ecc/bn128/bn128_field_elements.py
*/
public class AltBn128Fq2Point extends AbstractFieldPoint<AltBn128Fq2Point> {
private static BigInteger CURVE_ORDER =
new BigInteger(
"21888242871839275222246405745257275088548364400416034343698204186575808495617", 10);

public static AltBn128Fq2Point g2() {
final Fq2 x =
Expand Down Expand Up @@ -68,6 +71,10 @@ public boolean isOnCurve() {
return y.power(2).subtract(x.power(3)).equals(Fq2.b2());
}

public boolean isInGroup() {
return multiply(CURVE_ORDER).isInfinity();
}

@SuppressWarnings("rawtypes")
@Override
protected AltBn128Fq2Point newInstance(final FieldElement x, final FieldElement y) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ public class AltBN128PairingPrecompiledContract extends AbstractPrecompiledContr
private static final int FIELD_LENGTH = 32;
private static final int PARAMETER_LENGTH = 192;

private static final BytesValue FALSE =
static final BytesValue FALSE =
BytesValue.fromHexString(
"0x0000000000000000000000000000000000000000000000000000000000000000");
private static final BytesValue TRUE =
static final BytesValue TRUE =
BytesValue.fromHexString(
"0x0000000000000000000000000000000000000000000000000000000000000001");

Expand Down Expand Up @@ -79,7 +79,7 @@ public BytesValue compute(final BytesValue input, final MessageFrame messageFram
final Fq2 p2_x = Fq2.create(p2_xReal, p2_xImag);
final Fq2 p2_y = Fq2.create(p2_yReal, p2_yImag);
final AltBn128Fq2Point p2 = new AltBn128Fq2Point(p2_x, p2_y);
if (!p2.isOnCurve()) {
if (!p2.isOnCurve() || !p2.isInGroup()) {
return null;
}
b.add(p2);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/*
* Copyright 2019 ConsenSys AG.
*
* 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.pantheon.ethereum.mainnet.precompiles;

import static org.assertj.core.api.Assertions.assertThat;

import tech.pegasys.pantheon.ethereum.vm.GasCalculator;
import tech.pegasys.pantheon.ethereum.vm.MessageFrame;
import tech.pegasys.pantheon.util.bytes.BytesValue;
import tech.pegasys.pantheon.util.bytes.BytesValues;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class AltBN128PairingPrecompiledContractTest {

@Mock MessageFrame messageFrame;
@Mock GasCalculator gasCalculator;
final AltBN128PairingPrecompiledContract precompile =
new AltBN128PairingPrecompiledContract(gasCalculator);

@Test
public void compute_validPoints() {
final BytesValue g1Point0 =
BytesValues.concatenate(
BytesValue.fromHexString(
"0x0000000000000000000000000000000000000000000000000000000000000001"),
BytesValue.fromHexString(
"0x0000000000000000000000000000000000000000000000000000000000000002"));
final BytesValue g2Point0 =
BytesValues.concatenate(
BytesValue.fromHexString(
"0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2"),
BytesValue.fromHexString(
"0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed"),
BytesValue.fromHexString(
"0x090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b"),
BytesValue.fromHexString(
"0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa"));
final BytesValue g1Point1 =
BytesValues.concatenate(
BytesValue.fromHexString(
"0x0000000000000000000000000000000000000000000000000000000000000001"),
BytesValue.fromHexString(
"0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd45"));
final BytesValue g2Point1 =
BytesValues.concatenate(
BytesValue.fromHexString(
"0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2"),
BytesValue.fromHexString(
"0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed"),
BytesValue.fromHexString(
"0x090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b"),
BytesValue.fromHexString(
"0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa"));

final BytesValue input = BytesValues.concatenate(g1Point0, g2Point0, g1Point1, g2Point1);
final BytesValue result = precompile.compute(input, messageFrame);
assertThat(result).isEqualTo(AltBN128PairingPrecompiledContract.TRUE);
}

@Test
public void compute_invalidPointsOutsideSubgroupG2() {
final BytesValue g1Point0 =
BytesValues.concatenate(
BytesValue.fromHexString(
"0x0000000000000000000000000000000000000000000000000000000000000001"),
BytesValue.fromHexString(
"0x0000000000000000000000000000000000000000000000000000000000000002"));
final BytesValue g2Point0 =
BytesValues.concatenate(
BytesValue.fromHexString(
"0x1382cd45e5674247f9c900b5c6f6cabbc189c2fabe2df0bf5acd84c97818f508"),
BytesValue.fromHexString(
"0x1246178655ab8f2f26956b189894b7eb93cd4215b9937e7969e44305f80f521e"),
BytesValue.fromHexString(
"0x08331c0a261a74e7e75db1232956663cbc88110f726159c5cba1857ecd03fa64"),
BytesValue.fromHexString(
"0x1fbf8045ce3e79b5cde4112d38bcd0efbdb1295d2eefdf58151ae309d7ded7db"));
final BytesValue g1Point1 =
BytesValues.concatenate(
BytesValue.fromHexString(
"0x0000000000000000000000000000000000000000000000000000000000000001"),
BytesValue.fromHexString(
"0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd45"));
final BytesValue g2Point1 =
BytesValues.concatenate(
BytesValue.fromHexString(
"0x1382cd45e5674247f9c900b5c6f6cabbc189c2fabe2df0bf5acd84c97818f508"),
BytesValue.fromHexString(
"0x1246178655ab8f2f26956b189894b7eb93cd4215b9937e7969e44305f80f521e"),
BytesValue.fromHexString(
"0x08331c0a261a74e7e75db1232956663cbc88110f726159c5cba1857ecd03fa64"),
BytesValue.fromHexString(
"0x1fbf8045ce3e79b5cde4112d38bcd0efbdb1295d2eefdf58151ae309d7ded7db"));

final BytesValue input = BytesValues.concatenate(g1Point0, g2Point0, g1Point1, g2Point1);
final BytesValue result = precompile.compute(input, messageFrame);
assertThat(result).isNull();
}
}

0 comments on commit 333135b

Please sign in to comment.