Skip to content

Commit

Permalink
Update to latest spec and test cases
Browse files Browse the repository at this point in the history
  • Loading branch information
benjaminion committed Dec 31, 2019
1 parent 95335bd commit 97c7c4a
Show file tree
Hide file tree
Showing 21 changed files with 2,083 additions and 1,959 deletions.
790 changes: 790 additions & 0 deletions util/src/main/java/tech/pegasys/artemis/util/hashToG2/Chains.java

Large diffs are not rendered by default.

782 changes: 41 additions & 741 deletions util/src/main/java/tech/pegasys/artemis/util/hashToG2/Helper.java

Large diffs are not rendered by default.

102 changes: 102 additions & 0 deletions util/src/main/java/tech/pegasys/artemis/util/hashToG2/IetfTools.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*
* 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.artemis.util.hashToG2;

import static com.google.common.base.Preconditions.checkArgument;

import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.crypto.Hash;

/** A collection of useful IETF standardised tools. */
public class IetfTools {

private static final int SHA256_HASH_SIZE = 32;
private static final int SHA256_BLOCK_SIZE = 64;

/**
* Standard HMAC SHA-256 based on https://tools.ietf.org/html/rfc2104
*
* @param text the data to be hashed
* @param key the key
* @return Bytes of the HMAC SHA-256 of the text with key
*/
static Bytes HMAC_SHA256(byte[] text, byte[] key) {

// SHA256 blocksize in bytes
int blockSize = SHA256_BLOCK_SIZE;
byte ipad = (byte) 0x36;
byte opad = (byte) 0x5c;

if (key.length > blockSize) {
key = Hash.sha2_256(key);
}

// Pad or truncate the key to the blocksize
byte[] ikmPadded = new byte[blockSize];
System.arraycopy(key, 0, ikmPadded, 0, key.length);

byte[] ikmXorIpad = new byte[blockSize];
byte[] ikmXorOpad = new byte[blockSize];
for (int i = 0; i < blockSize; i++) {
ikmXorIpad[i] = (byte) (ikmPadded[i] ^ ipad);
ikmXorOpad[i] = (byte) (ikmPadded[i] ^ opad);
}

return Hash.sha2_256(
Bytes.concatenate(
Bytes.wrap(ikmXorOpad),
Hash.sha2_256(Bytes.concatenate(Bytes.wrap(ikmXorIpad), Bytes.wrap(text)))));
}

/**
* Standard HKDF_Extract as defined at https://tools.ietf.org/html/rfc5869#section-2.2
*
* <p>Note that the arguments to HMAC_SHA-256 appear to be inverted in RFC5869.
*
* @param salt salt value (a non-secret random value)
* @param ikm input keying material
* @return a pseudorandom key (of HashLen octets)
*/
public static Bytes HKDF_Extract(Bytes salt, Bytes ikm) {
return HMAC_SHA256(ikm.toArray(), salt.toArray());
}

/**
* Standard HKDF_Expand as defined at https://tools.ietf.org/html/rfc5869#section-2.3
*
* @param prk a pseudorandom key of at least HashLen octets
* @param info optional context and application specific information
* @param length desired length of output keying material in octets
* @return output keying material (of `length` octets)
*/
public static Bytes HKDF_Expand(Bytes prk, Bytes info, int length) {
checkArgument(prk.size() >= SHA256_HASH_SIZE, "prk must be larger than the hash length.");
checkArgument(
length > 0 && length <= 255 * SHA256_HASH_SIZE,
"length must be non-zero and not more than " + 255 * SHA256_HASH_SIZE);
Bytes okm = Bytes.EMPTY;
Bytes tOld = Bytes.EMPTY;
int i = 1;
int remainder = length;
while (remainder > 0) {
Bytes tNew =
HMAC_SHA256(Bytes.concatenate(tOld, info, Bytes.of((byte) i)).toArray(), prk.toArray());
okm = Bytes.concatenate(okm, tNew);
i += 1;
remainder -= SHA256_HASH_SIZE;
tOld = tNew;
}
return okm.slice(0, length);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,20 @@ JacobianPoint neg() {
return new JacobianPoint(x, y.neg(), z);
}

/**
* Calculate the point multiplied by (2 ^ n)
*
* @param n the number of times to double the point
* @return the element to the multiplied by (2 ^ n)
*/
JacobianPoint dbls(int n) {
JacobianPoint result = new JacobianPoint(this);
while (n-- > 0) {
result = result.dbl();
}
return result;
}

/**
* Create the equivalent point in Milagro's ECP2 format.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ static FP fpFromHex(String hex) {
/**
* Negate a field point (convenience method)
*
* @param a the foeld point to negate
* @param a the field point to negate
* @return the negated field point
*/
static FP negate(FP a) {
Expand All @@ -71,7 +71,7 @@ static FP negate(FP a) {
/**
* Big-endian conversion of byte array into a BIG, modulo the field modulus.
*
* <p>As defined at https://tools.ietf.org/html/rfc3447#section-4.2
* <p>Based on https://tools.ietf.org/html/rfc3447#section-4.2
*
* @param b octet string to be converted
* @return corresponding nonnegative integer
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
* 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.artemis.util.hashToG2;

import static org.junit.jupiter.api.Assertions.*;
import static tech.pegasys.artemis.util.hashToG2.Chains.expChain;
import static tech.pegasys.artemis.util.hashToG2.Chains.mxChain;
import static tech.pegasys.artemis.util.hashToG2.FP2Immutable.ONE;
import static tech.pegasys.artemis.util.hashToG2.Util.bigFromHex;

import org.apache.milagro.amcl.BLS381.BIG;
import org.apache.milagro.amcl.BLS381.DBIG;
import org.apache.milagro.amcl.BLS381.ROM;
import org.junit.jupiter.api.Test;

class ChainsTest {

// The field modulus
private static final BIG P = new BIG(ROM.Modulus);

// The enormous exponent used in mapToCurve
private static final BIG THREE = new BIG(3);
private static final DBIGExtended EXPONENT =
new DBIGExtended(BIG.mul(P.plus(THREE), P.minus(THREE))).fshr(4);

/* Raise this element to a DBIG exponent. Used for testing expChain */
private static FP2Immutable pow(FP2Immutable a, DBIG exponent) {
FP2Immutable result = ONE;
DBIGExtended exp = new DBIGExtended(exponent);
FP2Immutable tmp = new FP2Immutable(a);
while (!exp.iszilch()) {
if (exp.isOdd()) {
result = result.mul(tmp);
}
tmp = tmp.sqr();
exp.shr(1);
}
return result;
}

@Test
void mxChainTest() {
JacobianPoint a =
new JacobianPoint(
new FP2Immutable(new BIG(1), new BIG(2)),
new FP2Immutable(new BIG(3), new BIG(4)),
new FP2Immutable(new BIG(5), new BIG(6)));
JacobianPoint expected =
new JacobianPoint(
new FP2Immutable(
"0x14eb89798ed67c7c0c9a7ab4627f64a9295fa5aa738b23bc41d7e57bc75e3cfec576007ea509a867a1746954aae2cca9",
"0x00d29230f0dd01305ad70a52ceed8ee8e88ee072b69d9a535065785228d324b339a8b3116461ecfaec453c303da68240"),
new FP2Immutable(
"0x0170b865e217be3a5ecd56a0470270453cbd51ad2c04e0ff053455380a5a6841e5b580ff5dddbdf664ddc25acfecba58",
"0x0020c819b3da9c3e6e856a5235a3bf28b2f1401340d3bd41deaad48d17cb1e100655dd7028f6cb1708dc239175f4205a"),
new FP2Immutable(
"0x00e34380275c83c4308fc707542a3ecefa0ca80aeffd3791bef2fc8fbfbbb970f41c34ed98454b5884f90a838eccb68a",
"0x05b84312465a31b1dbe87388923b6244befe2f355ebda12b88f133237cf2c13158f1253b9e2f09749beb4099338957a4"));
assertEquals(expected, mxChain(a));
}

@Test
void expChainTest() {
// An arbitrary element
FP2Immutable a =
new FP2Immutable(
bigFromHex(
"0x081d1f51370a9e6f59ed62fa605e891c40b20d98601fe7c3fa6a8efabcf0c1c3a0ff05963ab388a4b9ec4d35e97c0863"),
bigFromHex(
"0x01fbe48c2b138982f28317f684364327114adecadd94b599347bded08ef7b7ba22d814f1c64f1c77023ec9425383c184"));
FP2Immutable expected = pow(a, EXPONENT);
FP2Immutable actual = expChain(a);
assertEquals(expected, actual);
}

@Test
void h2ChainTest() {
// TODO
}


}
Loading

0 comments on commit 97c7c4a

Please sign in to comment.