add pow tests (vectors from tor), don't pass yet
This commit is contained in:
46
LICENSE-tor
Normal file
46
LICENSE-tor
Normal file
@ -0,0 +1,46 @@
|
||||
This file contains the license for Tor,
|
||||
a free software project to provide anonymity on the Internet.
|
||||
|
||||
It also lists the licenses for other components used by Tor.
|
||||
|
||||
For more information about Tor, see https://www.torproject.org/.
|
||||
|
||||
If you got this file as a part of a larger bundle,
|
||||
there may be other license terms that you should be aware of.
|
||||
|
||||
===============================================================================
|
||||
Tor is distributed under the "3-clause BSD" license, a commonly used
|
||||
software license that means Tor is both free software and open source:
|
||||
|
||||
Copyright (c) 2001-2004, Roger Dingledine
|
||||
Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson
|
||||
Copyright (c) 2007-2019, The Tor Project, Inc.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
* Neither the names of the copyright owners nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
===============================================================================
|
@ -15,19 +15,19 @@ import net.i2p.pow.equix.Heap;
|
||||
import net.i2p.pow.hashx.HXCtx;
|
||||
|
||||
public class POW {
|
||||
private static final byte[] P = DataHelper.getASCII("Tor hs intro v1\0");
|
||||
private static final int SEED_LEN = 32;
|
||||
private static final int NONCE_LEN = 16;
|
||||
private static final int EFFORT_LEN = 4;
|
||||
public static final byte[] P = DataHelper.getASCII("Tor hs intro v1\0");
|
||||
public static final int SEED_LEN = 32;
|
||||
public static final int NONCE_LEN = 16;
|
||||
public static final int EFFORT_LEN = 4;
|
||||
// 100
|
||||
private static final int CHALLENGE_LEN = P.length + Hash.HASH_LENGTH + SEED_LEN + NONCE_LEN + EFFORT_LEN;
|
||||
private static final int SOLUTION_LEN = 16;
|
||||
private static final int SEED_PFX_LEN = 4;
|
||||
public static final int CHALLENGE_LEN = P.length + Hash.HASH_LENGTH + SEED_LEN + NONCE_LEN + EFFORT_LEN;
|
||||
public static final int SOLUTION_LEN = 16;
|
||||
public static final int SEED_PFX_LEN = 4;
|
||||
// 116
|
||||
private static final int CHECK_LEN = CHALLENGE_LEN + SOLUTION_LEN;
|
||||
public static final int CHECK_LEN = CHALLENGE_LEN + SOLUTION_LEN;
|
||||
// 40
|
||||
private static final int PROOF_LEN = NONCE_LEN + SOLUTION_LEN + EFFORT_LEN + SEED_PFX_LEN;
|
||||
private static final int BLAKE2B_32_LEN = 4;
|
||||
public static final int PROOF_LEN = NONCE_LEN + SOLUTION_LEN + EFFORT_LEN + SEED_PFX_LEN;
|
||||
public static final int BLAKE2B_32_LEN = 4;
|
||||
|
||||
/**
|
||||
* @return 40 byte proof
|
||||
@ -127,7 +127,8 @@ public class POW {
|
||||
if (claimedEffort > effort) {
|
||||
System.out.println("Proof effort " + claimedEffort + " is more than required effort " + effort);
|
||||
// replace effort in proof so it will validate
|
||||
DataHelper.toLong(proof, P.length + Hash.HASH_LENGTH + SEED_LEN + NONCE_LEN, 4, effort);
|
||||
// no, can't do this
|
||||
//DataHelper.toLong(proof, NONCE_LEN, 4, effort);
|
||||
}
|
||||
char[] solution = new char[8];
|
||||
off = NONCE_LEN + EFFORT_LEN;
|
||||
|
158
src/java/net/i2p/pow/Test.java
Normal file
158
src/java/net/i2p/pow/Test.java
Normal file
@ -0,0 +1,158 @@
|
||||
package net.i2p.pow;
|
||||
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.Hash;
|
||||
|
||||
import net.i2p.pow.equix.Heap;
|
||||
import net.i2p.pow.hashx.HXCtx;
|
||||
|
||||
/**
|
||||
* Vectors from Tor test_hs_pow.c
|
||||
*
|
||||
* Copyright (c) 2020-2023, The Tor Project, Inc.
|
||||
* See LICENSE for licensing information
|
||||
*/
|
||||
public class Test {
|
||||
private static int test_no;
|
||||
|
||||
/*
|
||||
static const struct {
|
||||
uint32_t claimed_effort;
|
||||
uint32_t validated_effort;
|
||||
int expected_retval;
|
||||
const char *seed_hex;
|
||||
const char *service_blinded_id_hex;
|
||||
const char *nonce_hex;
|
||||
const char *sol_hex;
|
||||
const char *encoded_hex;
|
||||
} vectors[] = {
|
||||
*/
|
||||
private static final int[] claimed = { 1, 0, 1000000, 1000000, 999999, 1000000, 1000000 };
|
||||
private static final int[] validated = { 0, 0, 1000000, 0, 0, 0, 1000000 };
|
||||
private static final int[] retval = { -1, 0, 0, -1, -1, -1, 0 };
|
||||
|
||||
private static final String[] V0 =
|
||||
{
|
||||
/* All zero, expect invalid */
|
||||
//1, 0, -1,
|
||||
"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"1111111111111111111111111111111111111111111111111111111111111111",
|
||||
"00000000000000000000000000000000", "00000000000000000000000000000000",
|
||||
"01" +
|
||||
"00000000000000000000000000000000" +
|
||||
"00000001" + "00000000" +
|
||||
"00000000000000000000000000000000"
|
||||
};
|
||||
private static final String[] V1 =
|
||||
{
|
||||
/* Valid zero-effort solution */
|
||||
//0, 0, 0,
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"1111111111111111111111111111111111111111111111111111111111111111",
|
||||
"55555555555555555555555555555555", "4312f87ceab844c78e1c793a913812d7",
|
||||
"01" +
|
||||
"55555555555555555555555555555555" +
|
||||
"00000000" + "aaaaaaaa" +
|
||||
"4312f87ceab844c78e1c793a913812d7"
|
||||
};
|
||||
private static final String[] V2 =
|
||||
{
|
||||
/* Valid high-effort solution */
|
||||
//1000000, 1000000, 0,
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"1111111111111111111111111111111111111111111111111111111111111111",
|
||||
"59217255555555555555555555555555", "0f3db97b9cac20c1771680a1a34848d3",
|
||||
"01" +
|
||||
"59217255555555555555555555555555" +
|
||||
"000f4240" + "aaaaaaaa" +
|
||||
"0f3db97b9cac20c1771680a1a34848d3"
|
||||
};
|
||||
private static final String[] V3 =
|
||||
{
|
||||
/* Reject replays */
|
||||
//1000000, 0, -1,
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"1111111111111111111111111111111111111111111111111111111111111111",
|
||||
"59217255555555555555555555555555", "0f3db97b9cac20c1771680a1a34848d3",
|
||||
"01" +
|
||||
"59217255555555555555555555555555" +
|
||||
"000f4240" + "aaaaaaaa" +
|
||||
"0f3db97b9cac20c1771680a1a34848d3"
|
||||
};
|
||||
private static final String[] V4 =
|
||||
{
|
||||
/* The claimed effort must exactly match what's in the challenge */
|
||||
//99999, 0, -1,
|
||||
"86fb0acf4932cda44dbb451282f415479462dd10cb97ff5e7e8e2a53c3767a7f",
|
||||
"bfd298428562e530c52bdb36d81a0e293ef4a0e94d787f0f8c0c611f4f9e78ed",
|
||||
"2eff9fdbc34326d9d2f18ed277469c63", "400cb091139f86b352119f6e131802d6",
|
||||
"01" +
|
||||
"2eff9fdbc34326d9d2f18ed277469c63" +
|
||||
"0001869f" + "86fb0acf" +
|
||||
"400cb091139f86b352119f6e131802d6"
|
||||
};
|
||||
private static final String[] V5 =
|
||||
{
|
||||
/* Otherwise good solution but with a corrupted nonce */
|
||||
//100000, 0, -1,
|
||||
"86fb0acf4932cda44dbb451282f415479462dd10cb97ff5e7e8e2a53c3767a7f",
|
||||
"bfd298428562e530c52bdb36d81a0e293ef4a0e94d787f0f8c0c611f4f9e78ed",
|
||||
"2eff9fdbc34326d9a2f18ed277469c63", "400cb091139f86b352119f6e131802d6",
|
||||
"01" +
|
||||
"2eff9fdbc34326d9a2f18ed277469c63" +
|
||||
"000186a0" + "86fb0acf" +
|
||||
"400cb091139f86b352119f6e131802d6"
|
||||
};
|
||||
private static final String[] V6 =
|
||||
{
|
||||
/* Corrected version of above */
|
||||
//100000, 100000, 0,
|
||||
"86fb0acf4932cda44dbb451282f415479462dd10cb97ff5e7e8e2a53c3767a7f",
|
||||
"bfd298428562e530c52bdb36d81a0e293ef4a0e94d787f0f8c0c611f4f9e78ed",
|
||||
"2eff9fdbc34326d9d2f18ed277469c63", "400cb091139f86b352119f6e131802d6",
|
||||
"01" +
|
||||
"2eff9fdbc34326d9d2f18ed277469c63" +
|
||||
"000186a0" + "86fb0acf" +
|
||||
"400cb091139f86b352119f6e131802d6"
|
||||
};
|
||||
|
||||
public static void main(String[] args) {
|
||||
test(V0, claimed[0], validated[0], retval[0]);
|
||||
test(V1, claimed[1], validated[1], retval[1]);
|
||||
test(V2, claimed[2], validated[2], retval[2]);
|
||||
test(V3, claimed[3], validated[3], retval[3]);
|
||||
test(V4, claimed[4], validated[4], retval[4]);
|
||||
test(V5, claimed[5], validated[5], retval[5]);
|
||||
test(V6, claimed[6], validated[6], retval[6]);
|
||||
}
|
||||
|
||||
private static void test(String[] v, int claimed, int validated, int retval) {
|
||||
System.out.println("Test " + (++test_no));
|
||||
byte[] seed = fromHex(v[0]);
|
||||
byte[] service_blinded_id = fromHex(v[1]);
|
||||
byte[] nonce = fromHex(v[2]);
|
||||
byte[] sol = fromHex(v[3]);
|
||||
byte[] encoded = fromHex(v[4]);
|
||||
HXCtx ctx = new HXCtx(512);
|
||||
Hash h = new Hash(service_blinded_id);
|
||||
byte[] proof = new byte[POW.PROOF_LEN];
|
||||
// nonce, effort, solution 16 + 4 + 16
|
||||
// skip the "01"
|
||||
System.arraycopy(encoded, 1, proof, 0, POW.NONCE_LEN + POW.EFFORT_LEN + POW.SOLUTION_LEN);
|
||||
// seed pfx
|
||||
System.arraycopy(seed, 0, proof, 36, POW.SEED_PFX_LEN);
|
||||
boolean ok = POW.verify(ctx, h, seed, validated, proof);
|
||||
System.out.println("Verify " + test_no + " expected " + (retval == 0) + " actual " + ok);
|
||||
ok = ok == (retval == 0);
|
||||
System.out.println("Test " + test_no + (ok ? " PASSED" : " FAILED"));
|
||||
}
|
||||
|
||||
private static byte[] fromHex(String v) {
|
||||
int sz = v.length() / 2;
|
||||
byte[] b = new byte[sz];
|
||||
for (int i = 0; i < sz; i++) {
|
||||
b[i] = (byte) (Integer.parseInt(v.substring(i*2, (i*2) + 2), 16) & 0xff);
|
||||
}
|
||||
return b;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user