├── .gitignore ├── LICENSE.md ├── README.md ├── pom.xml └── src ├── main ├── java │ └── edu │ │ └── stanford │ │ └── crypto │ │ ├── BlockingExecutor.java │ │ ├── ECConstants.java │ │ ├── ExperimentUtils.java │ │ ├── ProofUtils.java │ │ ├── SQLDatabase.java │ │ ├── bitcoin │ │ ├── Blockchain.java │ │ ├── BlockchainEntry.java │ │ ├── CustomerDatabase.java │ │ ├── CustomerSecretsDatabase.java │ │ ├── PrivateKeyDatabase.java │ │ ├── SQLBlockchain.java │ │ ├── SQLCustomerDatabase.java │ │ ├── SQLCustomerSecretsDatabase.java │ │ └── SQLPrivateKeyDatabase.java │ │ ├── database │ │ └── Database.java │ │ ├── experiments │ │ ├── AssetProofExperiment.java │ │ └── BalanceProofExperiment.java │ │ ├── proof │ │ ├── MemoryProof.java │ │ ├── Proof.java │ │ ├── ProofData.java │ │ ├── ProofSystem.java │ │ ├── RangeProof.java │ │ ├── RangeProofData.java │ │ ├── assets │ │ │ ├── AddressProof.java │ │ │ ├── AddressProofData.java │ │ │ ├── AddressProofEntry.java │ │ │ ├── AddressProofSystem.java │ │ │ ├── AssetProof.java │ │ │ ├── AssetProofData.java │ │ │ └── AssetProofSystem.java │ │ ├── balance │ │ │ ├── BalanceProof.java │ │ │ ├── BalanceProofData.java │ │ │ ├── BalanceProofSystem.java │ │ │ ├── CustomerInfo.java │ │ │ └── CustomerSecrets.java │ │ ├── binary │ │ │ ├── BinaryProof.java │ │ │ ├── BinaryProofData.java │ │ │ ├── BinaryProofSystem.java │ │ │ └── BinaryRangeProof.java │ │ └── rangeproof │ │ │ └── BinaryRangeProofSystem.java │ │ └── verification │ │ ├── AddressProofVerifier.java │ │ ├── AddressVerificationData.java │ │ ├── AssetsVerifier.java │ │ ├── BalanceVerificationData.java │ │ ├── BalanceVerifier.java │ │ ├── BinaryProofVerifier.java │ │ ├── BinaryRangeProofVerifier.java │ │ ├── GeneratorData.java │ │ ├── ParticipationData.java │ │ ├── ParticipationVerifier.java │ │ ├── RangeProofVerificationData.java │ │ ├── VerificationData.java │ │ └── Verifier.java └── resources │ └── log4j.properties └── test └── java └── edu └── stanford └── crypto ├── PlayGround.java └── proof └── assets ├── AddressProofTest.java └── RangeProofTest.java /.gitignore: -------------------------------------------------------------------------------- 1 | .classpath 2 | .project 3 | dependency-reduced-pom.xml 4 | target/ 5 | .settings/* 6 | *.swp 7 | *.json 8 | *.key 9 | *.proof 10 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 4 | 5 | Gaby G. Dagher, 6 | Benedikt Bunz, 7 | Joseph Bonneau, 8 | Jeremy Clark, 9 | Dan Boneh. 10 | 11 | Permission is hereby granted, free of charge, to any person obtaining a copy 12 | of this software and associated documentation files (the "Software"), to deal 13 | in the Software without restriction, including without limitation the rights 14 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | copies of the Software, and to permit persons to whom the Software is 16 | furnished to do so, subject to the following conditions: 17 | 18 | The above copyright notice and this permission notice shall be included in all 19 | copies or substantial portions of the Software. 20 | 21 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 27 | SOFTWARE. 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # provisions 2 | Provisions: Privacy-preserving proofs of solvency for Bitcoin 3 | https://eprint.iacr.org/2015/1008.pdf 4 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | edu.stanford.crypto 6 | bitcoinprovisions 7 | 0.0.1-SNAPSHOT 8 | jar 9 | 10 | bitcoinprovisions 11 | http://maven.apache.org 12 | 13 | 14 | UTF-8 15 | 1.7.7 16 | 17 | 2.0.2 18 | 19 | 20 | 21 | 22 | org.apache.maven.plugins 23 | maven-shade-plugin 24 | 2.3 25 | 26 | 27 | 28 | *:* 29 | 30 | META-INF/*.SF 31 | META-INF/*.DSA 32 | META-INF/*.RSA 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | package 41 | 42 | shade 43 | 44 | 45 | 46 | 47 | 48 | org.apache.maven.plugins 49 | maven-compiler-plugin 50 | 3.1 51 | 52 | 1.8 53 | 1.8 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | junit 66 | junit 67 | 4.12 68 | test 69 | 70 | 71 | 72 | org.easytesting 73 | fest-assert-core 74 | 2.0M10 75 | test 76 | 77 | 78 | 79 | org.bouncycastle 80 | bcpkix-jdk15on 81 | 1.54 82 | 83 | 84 | org.apache.logging.log4j 85 | log4j-api 86 | 2.5 87 | 88 | 89 | org.apache.logging.log4j 90 | log4j-core 91 | 2.5 92 | 93 | 94 | 95 | org.postgresql 96 | postgresql 97 | 9.4-1201-jdbc41 98 | 99 | 100 | 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/BlockingExecutor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto; 5 | 6 | import java.util.concurrent.ArrayBlockingQueue; 7 | import java.util.concurrent.ThreadPoolExecutor; 8 | import java.util.concurrent.TimeUnit; 9 | 10 | public class BlockingExecutor 11 | extends ThreadPoolExecutor { 12 | public BlockingExecutor() { 13 | super(Runtime.getRuntime().availableProcessors() - 1, Runtime.getRuntime().availableProcessors() - 1, 2, TimeUnit.DAYS, new ArrayBlockingQueue(Runtime.getRuntime().availableProcessors() * 4), new CallerRunsPolicy()); 14 | } 15 | } 16 | 17 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/ECConstants.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto; 5 | 6 | import org.bouncycastle.crypto.ec.CustomNamedCurves; 7 | import org.bouncycastle.math.ec.ECCurve; 8 | import org.bouncycastle.math.ec.ECFieldElement; 9 | import org.bouncycastle.math.ec.ECPoint; 10 | import org.bouncycastle.math.ec.custom.sec.SecP256K1Curve; 11 | import org.bouncycastle.math.ec.custom.sec.SecP256K1FieldElement; 12 | 13 | import java.math.BigInteger; 14 | import java.security.MessageDigest; 15 | import java.security.NoSuchAlgorithmException; 16 | 17 | public final class ECConstants { 18 | static { 19 | SecP256K1Curve curve = new SecP256K1Curve(); 20 | BigInteger hash = BigInteger.ZERO; 21 | try { 22 | MessageDigest sha256 = sha256 = MessageDigest.getInstance("SHA-256"); 23 | sha256.update("PROVISIONS".getBytes()); 24 | hash = new BigInteger(sha256.digest()); 25 | 26 | } catch (NoSuchAlgorithmException e) { 27 | e.printStackTrace(); 28 | } 29 | ECFieldElement x = new SecP256K1FieldElement(hash.mod(curve.getQ())); 30 | ECFieldElement rhs = x.square().multiply(x.add(curve.getA())).add(curve.getB()); 31 | ECFieldElement y = rhs.sqrt(); 32 | 33 | 34 | H = curve.validatePoint(x.toBigInteger(), y.toBigInteger()); 35 | 36 | 37 | } 38 | 39 | public static final ECCurve BITCOIN_CURVE = new SecP256K1Curve(); 40 | public static final ECPoint INFINITY = BITCOIN_CURVE.getInfinity(); 41 | public static final int STANDARD_SECURITY = 256; 42 | public static final int CHALLENGE_LENGTH = 256; 43 | public static final ECPoint G = CustomNamedCurves.getByName("secp256k1").getG(); 44 | public static final ECPoint H; 45 | public static final BigInteger Q = BITCOIN_CURVE.getOrder(); 46 | public static final BigInteger CHALLENGE_Q = Q.min(BigInteger.ONE.shiftLeft(256)); 47 | 48 | private ECConstants() { 49 | } 50 | } 51 | 52 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/ExperimentUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto; 5 | 6 | import edu.stanford.crypto.bitcoin.SQLBlockchain; 7 | import edu.stanford.crypto.bitcoin.SQLCustomerDatabase; 8 | import edu.stanford.crypto.bitcoin.SQLPrivateKeyDatabase; 9 | import org.bouncycastle.math.ec.ECPoint; 10 | 11 | import java.math.BigInteger; 12 | import java.sql.SQLException; 13 | import java.util.Random; 14 | import java.util.concurrent.ForkJoinTask; 15 | import java.util.concurrent.Semaphore; 16 | 17 | public class ExperimentUtils { 18 | public static void generateRandomCustomers(int numCustomers, int maxBits) throws SQLException { 19 | try { 20 | SQLCustomerDatabase database = new SQLCustomerDatabase(); 21 | try { 22 | database.truncate(); 23 | } finally { 24 | 25 | database.close(); 26 | 27 | } 28 | } catch (Exception e) { 29 | e.printStackTrace(); 30 | throw new RuntimeException(e); 31 | } 32 | Random rng = new Random(); 33 | int availableProcessors = Runtime.getRuntime().availableProcessors(); 34 | Semaphore semaphore = new Semaphore(0); 35 | int process = 0; 36 | while (process < availableProcessors) { 37 | SQLCustomerDatabase processDb = new SQLCustomerDatabase(); 38 | int processId = process++; 39 | ForkJoinTask.adapt(() -> { 40 | for (int i = processId; i < numCustomers; i += availableProcessors) { 41 | String customerId = "C" + i; 42 | BigInteger balance = rng.nextDouble() > 0.9 ? new BigInteger(maxBits, rng) : new BigInteger(10, rng); 43 | processDb.addBalance(customerId, balance); 44 | } 45 | try { 46 | processDb.close(); 47 | } catch (Exception e) { 48 | e.printStackTrace(); 49 | } 50 | semaphore.release(); 51 | } 52 | ).fork(); 53 | } 54 | try { 55 | semaphore.acquire(availableProcessors); 56 | } catch (InterruptedException e) { 57 | e.printStackTrace(); 58 | } 59 | } 60 | 61 | public static void generatePublicKeys(int numAddresses) throws SQLException { 62 | SQLBlockchain blockchain = new SQLBlockchain(); 63 | try { 64 | blockchain.truncate(); 65 | } finally { 66 | 67 | blockchain.close(); 68 | } 69 | Random rng = new Random(); 70 | int availableProcessors = Runtime.getRuntime().availableProcessors(); 71 | Semaphore semaphore = new Semaphore(0); 72 | int process = 0; 73 | while (process < availableProcessors) { 74 | SQLBlockchain processBlockchain = new SQLBlockchain(); 75 | SQLPrivateKeyDatabase privateKeyDatabase = new SQLPrivateKeyDatabase(); 76 | int processId = process++; 77 | ForkJoinTask.adapt(() -> { 78 | try { 79 | for (int i = processId; i < numAddresses; i += availableProcessors) { 80 | BigInteger privateKey = new BigInteger(256, rng); 81 | ECPoint publicKey = ECConstants.G.multiply(privateKey); 82 | BigInteger balance = new BigInteger(10, rng); 83 | processBlockchain.addEntry(publicKey, balance); 84 | if (rng.nextDouble() >= 0.05) continue; 85 | privateKeyDatabase.store(publicKey, privateKey); 86 | } 87 | } finally { 88 | try { 89 | privateKeyDatabase.close(); 90 | processBlockchain.close(); 91 | } catch (SQLException e) { 92 | e.printStackTrace(); 93 | } 94 | 95 | semaphore.release(); 96 | } 97 | } 98 | ).fork(); 99 | } 100 | try { 101 | semaphore.acquire(availableProcessors); 102 | } catch (InterruptedException e) { 103 | e.printStackTrace(); 104 | } 105 | } 106 | } 107 | 108 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/ProofUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto; 5 | 6 | import org.bouncycastle.math.ec.ECPoint; 7 | 8 | import java.math.BigInteger; 9 | import java.security.MessageDigest; 10 | import java.security.NoSuchAlgorithmException; 11 | import java.security.SecureRandom; 12 | 13 | public class ProofUtils { 14 | private static final ThreadLocal SHA256; 15 | private static final SecureRandom RNG; 16 | 17 | public static BigInteger computeChallenge(ECPoint ... points) { 18 | for (ECPoint point : points) { 19 | SHA256.get().update(point.getEncoded(false)); 20 | } 21 | byte[] hash = SHA256.get().digest(); 22 | return new BigInteger(hash).mod(ECConstants.CHALLENGE_Q); 23 | } 24 | 25 | public static BigInteger hash(String id, BigInteger salt) { 26 | SHA256.get().update(id.getBytes()); 27 | SHA256.get().update(salt.toByteArray()); 28 | return new BigInteger(SHA256.get().digest()); 29 | } 30 | 31 | public static BigInteger randomNumber(int bits) { 32 | return new BigInteger(bits, RNG); 33 | } 34 | 35 | public static BigInteger randomNumber() { 36 | return ProofUtils.randomNumber(256); 37 | } 38 | 39 | static { 40 | RNG = new SecureRandom(); 41 | SHA256 = ThreadLocal.withInitial(() -> { 42 | try { 43 | return MessageDigest.getInstance("SHA-256"); 44 | } 45 | catch (NoSuchAlgorithmException e) { 46 | e.printStackTrace(); 47 | throw new IllegalStateException(e); 48 | } 49 | } 50 | ); 51 | } 52 | } 53 | 54 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/SQLDatabase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto; 5 | 6 | import java.sql.SQLException; 7 | 8 | public interface SQLDatabase 9 | extends AutoCloseable { 10 | @Override 11 | void close() throws SQLException; 12 | } 13 | 14 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/bitcoin/Blockchain.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.bitcoin; 5 | 6 | import org.bouncycastle.math.ec.ECPoint; 7 | 8 | import java.math.BigInteger; 9 | import java.util.Iterator; 10 | 11 | interface Blockchain { 12 | BigInteger getBalance(ECPoint var1); 13 | 14 | void addEntry(ECPoint var1, BigInteger var2); 15 | 16 | Iterator getBlockchainEntries(); 17 | 18 | void truncate(); 19 | } 20 | 21 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/bitcoin/BlockchainEntry.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.bitcoin; 5 | 6 | import org.bouncycastle.math.ec.ECPoint; 7 | 8 | import java.math.BigInteger; 9 | 10 | public class BlockchainEntry { 11 | private final ECPoint pubKey; 12 | private final BigInteger balance; 13 | 14 | public BlockchainEntry(ECPoint pubKey, BigInteger balance) { 15 | this.pubKey = pubKey; 16 | this.balance = balance; 17 | } 18 | 19 | public ECPoint getPubKey() { 20 | return this.pubKey; 21 | } 22 | 23 | public BigInteger getBalance() { 24 | return this.balance; 25 | } 26 | } 27 | 28 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/bitcoin/CustomerDatabase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.bitcoin; 5 | 6 | import edu.stanford.crypto.proof.balance.CustomerInfo; 7 | 8 | import java.math.BigInteger; 9 | import java.util.Iterator; 10 | 11 | interface CustomerDatabase 12 | extends AutoCloseable { 13 | BigInteger getBalance(String var1); 14 | 15 | void addBalance(String var1, BigInteger var2); 16 | 17 | Iterator getCustomers(); 18 | 19 | void truncate(); 20 | } 21 | 22 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/bitcoin/CustomerSecretsDatabase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.bitcoin; 5 | 6 | import edu.stanford.crypto.proof.balance.CustomerSecrets; 7 | 8 | import java.math.BigInteger; 9 | 10 | public interface CustomerSecretsDatabase { 11 | void store(String var1, BigInteger var2, BigInteger var3); 12 | 13 | CustomerSecrets retrieve(String var1); 14 | } 15 | 16 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/bitcoin/PrivateKeyDatabase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.bitcoin; 5 | 6 | import org.bouncycastle.math.ec.ECPoint; 7 | 8 | import java.math.BigInteger; 9 | import java.util.Optional; 10 | 11 | public interface PrivateKeyDatabase { 12 | void store(ECPoint var1, BigInteger var2); 13 | 14 | Optional retrievePrivateKey(ECPoint var1); 15 | } 16 | 17 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/bitcoin/SQLBlockchain.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.bitcoin; 5 | 6 | import edu.stanford.crypto.ECConstants; 7 | import edu.stanford.crypto.SQLDatabase; 8 | import edu.stanford.crypto.database.Database; 9 | import org.bouncycastle.math.ec.ECPoint; 10 | 11 | import java.math.BigInteger; 12 | import java.sql.Connection; 13 | import java.sql.PreparedStatement; 14 | import java.sql.ResultSet; 15 | import java.sql.SQLException; 16 | import java.util.Iterator; 17 | 18 | public class SQLBlockchain 19 | implements Blockchain, 20 | SQLDatabase { 21 | private static final String INSERT_ENTRY_SQL = "INSERT INTO blockchain VALUES (?,?)"; 22 | private static final String LIST_ENTRIES_SQL = "SELECT public_key,balance FROM blockchain"; 23 | private static final String GET_BALANCE_SQL = "SELECT balance FROM blockchain WHERE public_key=?"; 24 | public static final String TRUNCATE_TABLE_SQL = "TRUNCATE TABLE asset_proof,asset_proof_secrets,blockchain"; 25 | private final Connection connection = Database.getConnection(); 26 | private final PreparedStatement getBalance; 27 | private final PreparedStatement insertEntry; 28 | private final PreparedStatement truncateDB; 29 | 30 | public SQLBlockchain() throws SQLException { 31 | getBalance = this.connection.prepareStatement("SELECT balance FROM blockchain WHERE public_key=?"); 32 | insertEntry = this.connection.prepareStatement("INSERT INTO blockchain VALUES (?,?)"); 33 | truncateDB = this.connection.prepareStatement("TRUNCATE TABLE asset_proof,asset_proof_secrets,blockchain"); 34 | } 35 | 36 | @Override 37 | public BigInteger getBalance(ECPoint publicKey) { 38 | try { 39 | this.getBalance.setBytes(1, publicKey.getEncoded(true)); 40 | ResultSet resultSet = this.getBalance.executeQuery(); 41 | if (resultSet.next()) { 42 | long balance = resultSet.getLong(1); 43 | return BigInteger.valueOf(balance); 44 | } 45 | } 46 | catch (SQLException e) { 47 | e.printStackTrace(); 48 | } 49 | throw new IllegalArgumentException("Can't find " + publicKey); 50 | } 51 | 52 | @Override 53 | public void addEntry(ECPoint pubKey, BigInteger balance) { 54 | try { 55 | this.insertEntry.setBytes(1, pubKey.getEncoded(true)); 56 | this.insertEntry.setLong(2, balance.longValueExact()); 57 | this.insertEntry.execute(); 58 | } 59 | catch (SQLException e) { 60 | e.printStackTrace(); 61 | } 62 | } 63 | 64 | @Override 65 | public Iterator getBlockchainEntries() { 66 | try { 67 | final ResultSet resultSet = this.connection.createStatement().executeQuery("SELECT public_key,balance FROM blockchain"); 68 | return new Iterator(){ 69 | 70 | @Override 71 | public boolean hasNext() { 72 | try { 73 | return resultSet.next(); 74 | } 75 | catch (SQLException e) { 76 | e.printStackTrace(); 77 | throw new IllegalStateException(e); 78 | } 79 | } 80 | 81 | @Override 82 | public BlockchainEntry next() { 83 | try { 84 | byte[] pubKey = resultSet.getBytes(1); 85 | long balance = resultSet.getLong(2); 86 | return new BlockchainEntry(ECConstants.BITCOIN_CURVE.decodePoint(pubKey), BigInteger.valueOf(balance)); 87 | } 88 | catch (SQLException e) { 89 | e.printStackTrace(); 90 | throw new IllegalStateException(e); 91 | } 92 | } 93 | }; 94 | } 95 | catch (SQLException e) { 96 | e.printStackTrace(); 97 | throw new IllegalStateException(e); 98 | } 99 | } 100 | 101 | @Override 102 | public void close() throws SQLException { 103 | this.connection.close(); 104 | } 105 | 106 | @Override 107 | public void truncate() { 108 | try { 109 | this.truncateDB.execute(); 110 | } 111 | catch (SQLException e) { 112 | e.printStackTrace(); 113 | } 114 | } 115 | 116 | } 117 | 118 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/bitcoin/SQLCustomerDatabase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.bitcoin; 5 | 6 | import edu.stanford.crypto.SQLDatabase; 7 | import edu.stanford.crypto.database.Database; 8 | import edu.stanford.crypto.proof.balance.CustomerInfo; 9 | 10 | import java.math.BigInteger; 11 | import java.sql.Connection; 12 | import java.sql.PreparedStatement; 13 | import java.sql.ResultSet; 14 | import java.sql.SQLException; 15 | import java.util.Iterator; 16 | 17 | public class SQLCustomerDatabase 18 | implements CustomerDatabase, 19 | SQLDatabase { 20 | public static final String QUERY_BALANCE_SQL = "SELECT balance FROM customer_balance WHERE customer_id=?"; 21 | public static final String LIST_CUSTOMERS_SQL = "SELECT customer_id,balance FROM customer_balance"; 22 | public static final String INSERT_CUSTOMER_SQL = "INSERT INTO customer_balance VALUES (?,?)"; 23 | public static final String TRUNCATE_TABLE_SQL = "TRUNCATE TABLE customer_balance,balance_proof_secrets"; 24 | private final PreparedStatement queryBalance; 25 | private final PreparedStatement listCustomers; 26 | private final PreparedStatement insertCustomer; 27 | private final PreparedStatement truncateDB; 28 | private final Connection connection = Database.getConnection(); 29 | 30 | public SQLCustomerDatabase() throws SQLException { 31 | this.queryBalance = this.connection.prepareStatement("SELECT balance FROM customer_balance WHERE customer_id=?"); 32 | this.listCustomers = this.connection.prepareStatement("SELECT customer_id,balance FROM customer_balance"); 33 | this.insertCustomer = this.connection.prepareStatement("INSERT INTO customer_balance VALUES (?,?)"); 34 | this.truncateDB = this.connection.prepareStatement("TRUNCATE TABLE customer_balance,balance_proof_secrets"); 35 | } 36 | 37 | @Override 38 | public BigInteger getBalance(String customerId) { 39 | try { 40 | this.queryBalance.setString(1, customerId); 41 | ResultSet resultSet = this.queryBalance.executeQuery(); 42 | if (resultSet.next()) { 43 | long balance = resultSet.getLong(1); 44 | return BigInteger.valueOf(balance); 45 | } 46 | throw new AssertionError((Object)("Customer not found " + customerId)); 47 | } 48 | catch (SQLException e) { 49 | e.printStackTrace(); 50 | throw new AssertionError(e); 51 | } 52 | } 53 | 54 | @Override 55 | public void addBalance(String customerId, BigInteger balance) { 56 | try { 57 | PreparedStatement statement = this.insertCustomer; 58 | statement.setString(1, customerId); 59 | statement.setLong(2, balance.longValueExact()); 60 | statement.execute(); 61 | } 62 | catch (SQLException e) { 63 | e.printStackTrace(); 64 | throw new IllegalStateException(e); 65 | } 66 | } 67 | 68 | @Override 69 | public Iterator getCustomers() { 70 | try { 71 | this.connection.setAutoCommit(false); 72 | final ResultSet resultSet = this.listCustomers.executeQuery(); 73 | resultSet.setFetchSize(1000); 74 | return new Iterator(){ 75 | 76 | @Override 77 | public boolean hasNext() { 78 | try { 79 | boolean hasNext = resultSet.next(); 80 | if (!hasNext) { 81 | SQLCustomerDatabase.this.connection.setAutoCommit(true); 82 | } 83 | return hasNext; 84 | } 85 | catch (SQLException e) { 86 | throw new IllegalStateException(e); 87 | } 88 | } 89 | 90 | @Override 91 | public CustomerInfo next() { 92 | try { 93 | String id = resultSet.getString(1); 94 | long balance = resultSet.getLong(2); 95 | return new CustomerInfo(id, BigInteger.valueOf(balance)); 96 | } 97 | catch (SQLException e) { 98 | throw new IllegalStateException(e); 99 | } 100 | } 101 | }; 102 | } 103 | catch (SQLException e) { 104 | e.printStackTrace(); 105 | throw new AssertionError(e); 106 | } 107 | } 108 | 109 | @Override 110 | public void truncate() { 111 | try { 112 | this.truncateDB.execute(); 113 | } 114 | catch (SQLException e) { 115 | e.printStackTrace(); 116 | } 117 | } 118 | 119 | @Override 120 | public void close() throws SQLException { 121 | this.connection.close(); 122 | } 123 | 124 | } 125 | 126 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/bitcoin/SQLCustomerSecretsDatabase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.bitcoin; 5 | 6 | import edu.stanford.crypto.SQLDatabase; 7 | import edu.stanford.crypto.database.Database; 8 | import edu.stanford.crypto.proof.balance.CustomerSecrets; 9 | 10 | import java.math.BigInteger; 11 | import java.sql.Connection; 12 | import java.sql.PreparedStatement; 13 | import java.sql.ResultSet; 14 | import java.sql.SQLException; 15 | 16 | public class SQLCustomerSecretsDatabase 17 | implements CustomerSecretsDatabase, 18 | SQLDatabase { 19 | public static final String RETRIEVE_SECRETS_SQL = "SELECT hash_salt,balance_salt FROM balance_proof_secrets WHERE customer_id=?"; 20 | public static final String INSERT_INTO_SQL = "INSERT INTO balance_proof_secrets VALUES (?,?,?)"; 21 | private final PreparedStatement retrieveSecrets; 22 | private final PreparedStatement insertSecrets; 23 | private final Connection connection = Database.getConnection(); 24 | 25 | public SQLCustomerSecretsDatabase() throws SQLException { 26 | this.retrieveSecrets = this.connection.prepareStatement("SELECT hash_salt,balance_salt FROM balance_proof_secrets WHERE customer_id=?"); 27 | this.insertSecrets = this.connection.prepareStatement("INSERT INTO balance_proof_secrets VALUES (?,?,?)"); 28 | } 29 | 30 | @Override 31 | public void store(String customerId, BigInteger hashSalt, BigInteger balanceSalt) { 32 | try { 33 | this.insertSecrets.setString(1, customerId); 34 | this.insertSecrets.setBytes(2, hashSalt.toByteArray()); 35 | this.insertSecrets.setBytes(3, balanceSalt.toByteArray()); 36 | this.insertSecrets.execute(); 37 | } 38 | catch (SQLException e) { 39 | e.printStackTrace(); 40 | } 41 | } 42 | 43 | @Override 44 | public CustomerSecrets retrieve(String customerId) { 45 | try { 46 | this.retrieveSecrets.setString(1, customerId); 47 | ResultSet resultSet = this.retrieveSecrets.executeQuery(); 48 | if (resultSet.next()) { 49 | BigInteger hashSalt = new BigInteger(resultSet.getBytes(1)); 50 | BigInteger balanceRandomness = new BigInteger(resultSet.getBytes(2)); 51 | return new CustomerSecrets(hashSalt, balanceRandomness); 52 | } 53 | throw new IllegalArgumentException("Customer not found " + customerId); 54 | } 55 | catch (SQLException e) { 56 | e.printStackTrace(); 57 | throw new IllegalArgumentException(e); 58 | } 59 | } 60 | 61 | @Override 62 | public void close() throws SQLException { 63 | this.connection.close(); 64 | } 65 | } 66 | 67 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/bitcoin/SQLPrivateKeyDatabase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.bitcoin; 5 | 6 | import edu.stanford.crypto.SQLDatabase; 7 | import edu.stanford.crypto.database.Database; 8 | import org.bouncycastle.math.ec.ECPoint; 9 | 10 | import java.math.BigInteger; 11 | import java.sql.Connection; 12 | import java.sql.PreparedStatement; 13 | import java.sql.ResultSet; 14 | import java.sql.SQLException; 15 | import java.util.Optional; 16 | 17 | public class SQLPrivateKeyDatabase 18 | implements PrivateKeyDatabase, 19 | SQLDatabase { 20 | public static final String RETRIEVE_SECRETS_SQL = "SELECT private_key FROM asset_proof_secrets WHERE public_key=?"; 21 | public static final String INSERT_INTO_SQL = "INSERT INTO asset_proof_secrets VALUES (?,?)"; 22 | private final PreparedStatement retrieveSecrets; 23 | private final PreparedStatement insertSecrets; 24 | private final Connection connection = Database.getConnection(); 25 | 26 | public SQLPrivateKeyDatabase() throws SQLException { 27 | this.retrieveSecrets = this.connection.prepareStatement("SELECT private_key FROM asset_proof_secrets WHERE public_key=?"); 28 | this.insertSecrets = this.connection.prepareStatement("INSERT INTO asset_proof_secrets VALUES (?,?)"); 29 | } 30 | 31 | @Override 32 | public void store(ECPoint publicKey, BigInteger privateKey) { 33 | try { 34 | this.insertSecrets.setBytes(1, publicKey.getEncoded(true)); 35 | this.insertSecrets.setBytes(2, privateKey.toByteArray()); 36 | this.insertSecrets.execute(); 37 | } 38 | catch (SQLException e) { 39 | e.printStackTrace(); 40 | } 41 | } 42 | 43 | @Override 44 | public Optional retrievePrivateKey(ECPoint publicKey) { 45 | try { 46 | this.retrieveSecrets.setBytes(1, publicKey.getEncoded(true)); 47 | ResultSet resultSet = this.retrieveSecrets.executeQuery(); 48 | if (resultSet.next()) { 49 | return Optional.of(new BigInteger(resultSet.getBytes(1))); 50 | } 51 | return Optional.empty(); 52 | } 53 | catch (SQLException e) { 54 | e.printStackTrace(); 55 | throw new IllegalArgumentException(e); 56 | } 57 | } 58 | 59 | @Override 60 | public void close() throws SQLException { 61 | this.connection.close(); 62 | } 63 | } 64 | 65 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/database/Database.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.database; 5 | 6 | import java.net.UnknownHostException; 7 | import java.sql.*; 8 | 9 | public final class Database { 10 | public static final String URL = "jdbc:postgresql://127.0.0.1/provisions"; 11 | public static final String USER = "admin"; 12 | public static final String PASSWORD = "password"; 13 | 14 | private Database() throws UnknownHostException, ClassNotFoundException, SQLException { 15 | } 16 | 17 | public static Connection getConnection() throws SQLException { 18 | DriverManager.setLoginTimeout(10); 19 | return DriverManager.getConnection(URL, USER, PASSWORD); 20 | } 21 | 22 | public static void clearProofs() { 23 | try { 24 | Connection connection = Database.getConnection(); 25 | Throwable throwable = null; 26 | try { 27 | Statement statement = connection.createStatement(); 28 | statement.execute("TRUNCATE TABLE balance_proof,balance_proof_secrets,asset_proof"); 29 | } 30 | catch (Throwable statement) { 31 | throwable = statement; 32 | throw statement; 33 | } 34 | finally { 35 | if (connection != null) { 36 | if (throwable != null) { 37 | try { 38 | connection.close(); 39 | } 40 | catch (Throwable statement) { 41 | throwable.addSuppressed(statement); 42 | } 43 | } else { 44 | connection.close(); 45 | } 46 | } 47 | } 48 | } 49 | catch (SQLException e) { 50 | e.printStackTrace(); 51 | throw new IllegalStateException(e); 52 | } 53 | } 54 | 55 | public static void createTables() throws SQLException { 56 | Connection connection = Database.getConnection(); 57 | String CREATE_BALANCE_TABLE_SQL = "CREATE TABLE IF NOT EXISTS balance_proof ( customer_id_hash BYTEA NOT NULL,\n range_proof BYTEA,\n CONSTRAINT balance_proof_pkey PRIMARY KEY (customer_id_hash)\n)WITH ( OIDS=FALSE);ALTER TABLE balance_proof OWNER TO USER"; 58 | PreparedStatement createBalanceStatement = connection.prepareStatement(CREATE_BALANCE_TABLE_SQL); 59 | createBalanceStatement.execute(); 60 | String CREATE_BALANCE_SECRETS_TABLE_SQL = "CREATE TABLE IF NOT EXISTS balance_proof_secrets\n(\n customer_id CHARACTER VARYING(9) NOT NULL,\n hash_salt BYTEA,\n balance_salt BYTEA,\n CONSTRAINT balance_proof_secrets_pkey PRIMARY KEY (customer_id),\n CONSTRAINT balance_proof_secrets_customer_id_fkey FOREIGN KEY (customer_id)\n REFERENCES customer_balance (customer_id) MATCH SIMPLE\n ON UPDATE CASCADE ON DELETE CASCADE\n)\nWITH (\n OIDS=FALSE\n);\nALTER TABLE balance_proof_secrets\n OWNER TO USER;"; 61 | PreparedStatement createBalanceSecretsTable = connection.prepareStatement(CREATE_BALANCE_SECRETS_TABLE_SQL); 62 | createBalanceSecretsTable.execute(); 63 | String CREATE_CUSTOMER_BALANCE = "CREATE TABLE IF NOT EXISTS customer_balance\n(\n customer_id CHARACTER VARYING(9) NOT NULL,\n balance BIGINT,\n CONSTRAINT customer_balance_pkey PRIMARY KEY (customer_id)\n)\nWITH (\n OIDS=FALSE\n);\nALTER TABLE customer_balance\n OWNER TO USER;\n"; 64 | PreparedStatement createCustomerBalance = connection.prepareStatement(CREATE_CUSTOMER_BALANCE); 65 | createCustomerBalance.execute(); 66 | String CREATE_ASSETS_TABLE_SQL = "CREATE TABLE IF NOT EXISTS assets_proof(hash_salt BYTEA,balance_salt BYTEA);"; 67 | PreparedStatement createAssetsTable = connection.prepareStatement(CREATE_ASSETS_TABLE_SQL); 68 | createAssetsTable.execute(); 69 | String CREATE_BLOCKCHAIN_SQL = "CREATE TABLE IF NOT EXISTS blockchain\n(\n pubkey BYTEA NOT NULL,\n balance BIGINT,\n CONSTRAINT blockchain_pkey PRIMARY KEY (pubkey)\n)\nWITH (\n OIDS=FALSE\n);\nALTER TABLE blockchain\n OWNER TO USER;"; 70 | PreparedStatement createBlockchain = connection.prepareStatement(CREATE_BLOCKCHAIN_SQL); 71 | createBlockchain.execute(); 72 | String CREATE_ASSET_PROOF_SQL = "CREATE TABLE IF NOT EXISTS asset_proof\n(\n public_key BYTEA NOT NULL,\n main_proof BYTEA,\n binary_proof BYTEA,\n CONSTRAINT asset_proof_pkey PRIMARY KEY (public_key),\n CONSTRAINT asset_proof_public_key_fkey FOREIGN KEY (public_key)\n REFERENCES blockchain (public_key) MATCH SIMPLE\n ON UPDATE NO ACTION ON DELETE NO ACTION\n)\nWITH (\n OIDS=FALSE\n);\nALTER TABLE asset_proof\n OWNER TO USER;\n"; 73 | PreparedStatement createAssetProof = connection.prepareStatement(CREATE_ASSET_PROOF_SQL); 74 | createAssetProof.execute(); 75 | String CREATE_ASSET_PROOF_SECRETS_SQL = "CREATE TABLE IF NOT EXISTS asset_proof_secrets \n(\n public_key BYTEA NOT NULL,\n private_key BYTEA,\n CONSTRAINT asset_proof_secrets_pkey PRIMARY KEY (public_key),\n CONSTRAINT asset_proof_secrets_public_key_fkey FOREIGN KEY (public_key)\n REFERENCES blockchain (public_key) MATCH SIMPLE\n ON UPDATE NO ACTION ON DELETE NO ACTION\n)\nWITH (\n OIDS=FALSE\n);\nALTER TABLE asset_proof_secrets\n OWNER TO USER;\n"; 76 | PreparedStatement createAssetProofSecrets = connection.prepareStatement(CREATE_ASSET_PROOF_SECRETS_SQL); 77 | createAssetProofSecrets.execute(); 78 | connection.close(); 79 | } 80 | } 81 | 82 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/experiments/AssetProofExperiment.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.experiments; 5 | 6 | import edu.stanford.crypto.ExperimentUtils; 7 | import edu.stanford.crypto.database.Database; 8 | import edu.stanford.crypto.proof.assets.AssetProof; 9 | import edu.stanford.crypto.proof.assets.AssetProofSystem; 10 | import edu.stanford.crypto.verification.AssetsVerifier; 11 | import edu.stanford.crypto.verification.GeneratorData; 12 | 13 | import java.io.IOException; 14 | import java.io.OutputStream; 15 | import java.nio.file.Files; 16 | import java.nio.file.OpenOption; 17 | import java.nio.file.Path; 18 | import java.nio.file.Paths; 19 | import java.sql.SQLException; 20 | 21 | public class AssetProofExperiment { 22 | public static void main(String[] args) throws IOException, SQLException { 23 | Path outputFile = Paths.get(args[0], new String[0]); 24 | OutputStream stream = Files.newOutputStream(outputFile, new OpenOption[0]); 25 | Throwable throwable = null; 26 | try { 27 | int[] numberOfAddresses; 28 | stream.write("Addresses;Proof Time;Verify time;File size\n".getBytes()); 29 | for (int numKeys : numberOfAddresses = new int[]{10, 100, 1000, 10000, 100000, 200000, 500000}) { 30 | AssetProofSystem proofSystem = new AssetProofSystem(); 31 | AssetsVerifier verifier = new AssetsVerifier(); 32 | GeneratorData data = new GeneratorData(); 33 | long startClearing = System.currentTimeMillis(); 34 | System.out.println("Starting to clear proofs "); 35 | Database.clearProofs(); 36 | long endClearing = System.currentTimeMillis(); 37 | System.out.println("Took " + (double)(endClearing - startClearing) / 1000.0 + "s"); 38 | ExperimentUtils.generatePublicKeys(numKeys); 39 | long endCreating = System.currentTimeMillis(); 40 | System.out.println("Took " + (double)(endCreating - endClearing) / 1000.0 + "s to create keys"); 41 | long startProof = System.currentTimeMillis(); 42 | AssetProof proof = proofSystem.createProof(null); 43 | long endProof = System.currentTimeMillis(); 44 | System.out.println("Finished balance proof in " + (endProof - startProof) / 1000 + "s"); 45 | verifier.verify(proof, data); 46 | long endVerifyFull = System.currentTimeMillis(); 47 | System.out.println("Finished verification in " + (endVerifyFull - endProof) / 1000 + "s"); 48 | stream.write(("" + numKeys + ";" + (endProof - startProof) + ";" + (endVerifyFull - endProof) + ";" + proof.getSizeInfo() + "\n").getBytes()); 49 | stream.flush(); 50 | proof.close(); 51 | System.out.println("Connections closed"); 52 | } 53 | } 54 | catch (Throwable numberOfAddresses) { 55 | throwable = numberOfAddresses; 56 | throw numberOfAddresses; 57 | } 58 | finally { 59 | if (stream != null) { 60 | if (throwable != null) { 61 | try { 62 | stream.close(); 63 | } 64 | catch (Throwable numberOfAddresses) { 65 | throwable.addSuppressed(numberOfAddresses); 66 | } 67 | } else { 68 | stream.close(); 69 | } 70 | } 71 | } 72 | System.out.println("Proof Sucess"); 73 | } 74 | } 75 | 76 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/experiments/BalanceProofExperiment.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.experiments; 5 | 6 | import edu.stanford.crypto.ExperimentUtils; 7 | import edu.stanford.crypto.bitcoin.SQLCustomerDatabase; 8 | import edu.stanford.crypto.bitcoin.SQLCustomerSecretsDatabase; 9 | import edu.stanford.crypto.database.Database; 10 | import edu.stanford.crypto.proof.balance.BalanceProof; 11 | import edu.stanford.crypto.proof.balance.BalanceProofData; 12 | import edu.stanford.crypto.proof.balance.BalanceProofSystem; 13 | import edu.stanford.crypto.proof.balance.CustomerSecrets; 14 | import edu.stanford.crypto.verification.BalanceVerificationData; 15 | import edu.stanford.crypto.verification.BalanceVerifier; 16 | import edu.stanford.crypto.verification.ParticipationData; 17 | import edu.stanford.crypto.verification.ParticipationVerifier; 18 | 19 | import java.io.IOException; 20 | import java.io.OutputStream; 21 | import java.math.BigInteger; 22 | import java.nio.file.Files; 23 | import java.nio.file.OpenOption; 24 | import java.nio.file.Path; 25 | import java.nio.file.Paths; 26 | import java.sql.SQLException; 27 | 28 | public class BalanceProofExperiment { 29 | public static void main(String[] args) throws IOException, SQLException { 30 | Path outputFile = Paths.get(args[0], new String[0]); 31 | OutputStream stream = Files.newOutputStream(outputFile, new OpenOption[0]); 32 | Throwable throwable = null; 33 | try { 34 | stream.write("Bits;Customers;Proof Time;Verify time;Participation verify;File size\n".getBytes()); 35 | int[] numberOfCustomers = new int[]{100, 200000, 2000000}; 36 | int[] numberOfBits = new int[]{51}; 37 | BalanceProofSystem proofSystem = new BalanceProofSystem(); 38 | BalanceVerifier verifier = new BalanceVerifier(); 39 | ParticipationVerifier participationVerifier = new ParticipationVerifier(); 40 | for (int customers : numberOfCustomers) { 41 | for (int bits : numberOfBits) { 42 | long startClearing = System.currentTimeMillis(); 43 | System.out.println("Starting to clear proofs "); 44 | Database.clearProofs(); 45 | long endClearing = System.currentTimeMillis(); 46 | System.out.println("Took " + (double)(endClearing - startClearing) / 1000.0 + "s"); 47 | ExperimentUtils.generateRandomCustomers(customers, bits); 48 | long endCreating = System.currentTimeMillis(); 49 | System.out.println("Took " + (double)(endCreating - endClearing) / 1000.0 + "s to create customers"); 50 | BalanceProofData data = new BalanceProofData(bits); 51 | long startProof = System.currentTimeMillis(); 52 | BalanceProof proof = proofSystem.createProof(data); 53 | long endProof = System.currentTimeMillis(); 54 | System.out.println("Finished balance proof in " + (endProof - startProof) / 1000 + "s"); 55 | verifier.verify(proof, new BalanceVerificationData(bits)); 56 | long endVerifyFull = System.currentTimeMillis(); 57 | System.out.println("Finished verification in " + (endVerifyFull - endProof) / 1000 + "s"); 58 | String customer = "C0"; 59 | SQLCustomerDatabase customerDatabase = new SQLCustomerDatabase(); 60 | Throwable throwable2 = null; 61 | try { 62 | SQLCustomerSecretsDatabase secretsDatabase = new SQLCustomerSecretsDatabase(); 63 | Throwable throwable3 = null; 64 | try { 65 | CustomerSecrets secrets = secretsDatabase.retrieve(customer); 66 | BigInteger balance = customerDatabase.getBalance(customer); 67 | ParticipationData participationData = new ParticipationData(customer, secrets, balance); 68 | participationVerifier.verify(proof, participationData); 69 | } 70 | catch (Throwable secrets) { 71 | throwable3 = secrets; 72 | throw secrets; 73 | } 74 | finally { 75 | if (secretsDatabase != null) { 76 | if (throwable3 != null) { 77 | try { 78 | secretsDatabase.close(); 79 | } 80 | catch (Throwable secrets) { 81 | throwable3.addSuppressed(secrets); 82 | } 83 | } else { 84 | secretsDatabase.close(); 85 | } 86 | } 87 | } 88 | } 89 | catch (Throwable secretsDatabase) { 90 | throwable2 = secretsDatabase; 91 | throw secretsDatabase; 92 | } 93 | finally { 94 | if (customerDatabase != null) { 95 | if (throwable2 != null) { 96 | try { 97 | customerDatabase.close(); 98 | } 99 | catch (Throwable secretsDatabase) { 100 | throwable2.addSuppressed(secretsDatabase); 101 | } 102 | } else { 103 | customerDatabase.close(); 104 | } 105 | } 106 | } 107 | long endVerifyParticipation = System.currentTimeMillis(); 108 | stream.write(("" + bits + ";" + customers + ";" + (endProof - startProof) + ";" + (endVerifyFull - endProof) + ";" + (endVerifyParticipation - endVerifyFull) + ";" + proof.getSizeInfo() + "\n").getBytes()); 109 | stream.flush(); 110 | proof.close(); 111 | System.out.println("Connections closed"); 112 | } 113 | } 114 | } 115 | catch (Throwable numberOfCustomers) { 116 | throwable = numberOfCustomers; 117 | throw numberOfCustomers; 118 | } 119 | finally { 120 | if (stream != null) { 121 | if (throwable != null) { 122 | try { 123 | stream.close(); 124 | } 125 | catch (Throwable numberOfCustomers) { 126 | throwable.addSuppressed(numberOfCustomers); 127 | } 128 | } else { 129 | stream.close(); 130 | } 131 | } 132 | } 133 | System.out.println("Proof Sucess"); 134 | } 135 | } 136 | 137 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/proof/MemoryProof.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.proof; 5 | 6 | public interface MemoryProof 7 | extends Proof { 8 | byte[] serialize(); 9 | } 10 | 11 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/proof/Proof.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.proof; 5 | 6 | public interface Proof { 7 | } 8 | 9 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/proof/ProofData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.proof; 5 | 6 | public interface ProofData

{ 7 | } 8 | 9 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/proof/ProofSystem.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.proof; 5 | 6 | public interface ProofSystem

> { 7 | P createProof(T var1); 8 | } 9 | 10 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/proof/RangeProof.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.proof; 5 | 6 | import org.bouncycastle.math.ec.ECPoint; 7 | 8 | import java.math.BigInteger; 9 | 10 | public interface RangeProof 11 | extends MemoryProof { 12 | BigInteger getRange(); 13 | 14 | ECPoint getStatement(); 15 | } 16 | 17 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/proof/RangeProofData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.proof; 5 | 6 | import edu.stanford.crypto.ECConstants; 7 | import edu.stanford.crypto.proof.binary.BinaryRangeProof; 8 | 9 | import java.math.BigInteger; 10 | import java.util.List; 11 | import java.util.stream.IntStream; 12 | 13 | public class RangeProofData 14 | implements ProofData { 15 | private final BigInteger secret; 16 | private final List randomnes; 17 | 18 | public RangeProofData(BigInteger secret, List randomnes) { 19 | if (secret.bitLength() > randomnes.size()) { 20 | throw new IllegalArgumentException("What are you trying to have me proof here?"); 21 | } 22 | this.secret = secret; 23 | this.randomnes = randomnes; 24 | } 25 | 26 | public BigInteger getSecret() { 27 | return this.secret; 28 | } 29 | 30 | public List getRandomnes() { 31 | return this.randomnes; 32 | } 33 | 34 | public BigInteger getTotalRandomness() { 35 | return IntStream.range(0, this.randomnes.size()).mapToObj(i -> this.randomnes.get(i).shiftLeft(i)).reduce(BigInteger.ZERO, BigInteger::add).mod(ECConstants.Q); 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/proof/assets/AddressProof.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.proof.assets; 5 | 6 | import edu.stanford.crypto.ECConstants; 7 | import edu.stanford.crypto.proof.MemoryProof; 8 | import org.bouncycastle.math.ec.ECPoint; 9 | 10 | import java.math.BigInteger; 11 | import java.util.Arrays; 12 | import java.util.List; 13 | 14 | public class AddressProof 15 | implements MemoryProof { 16 | private final ECPoint commitmentBalance; 17 | private final ECPoint commitmentXHat; 18 | private final BigInteger challengeZero; 19 | private final BigInteger challengeOne; 20 | 21 | private final BigInteger responseS; 22 | private final BigInteger responseV; 23 | private final BigInteger responseT; 24 | private final BigInteger responseXHat; 25 | private final BigInteger responseZero; 26 | private final BigInteger responseOne; 27 | 28 | public AddressProof(ECPoint commitmentBalance, ECPoint commitmentXHat, BigInteger challengeZero, BigInteger challengeOne, BigInteger responseS, BigInteger responseV, BigInteger responseT, BigInteger responseXHat, BigInteger responseZero, BigInteger responseOne) { 29 | this.commitmentBalance = commitmentBalance; 30 | this.commitmentXHat = commitmentXHat; 31 | this.challengeZero = challengeZero; 32 | this.challengeOne = challengeOne; 33 | this.responseS = responseS; 34 | this.responseV = responseV; 35 | this.responseT = responseT; 36 | this.responseXHat = responseXHat; 37 | this.responseZero = responseZero; 38 | this.responseOne = responseOne; 39 | } 40 | 41 | public AddressProof(byte[] array) { 42 | int index = 0; 43 | byte statementLength = array[index++]; 44 | this.commitmentBalance = ECConstants.BITCOIN_CURVE.decodePoint(Arrays.copyOfRange(array, index, statementLength + index)); 45 | index += statementLength; 46 | statementLength = array[index++]; 47 | this.commitmentXHat = ECConstants.BITCOIN_CURVE.decodePoint(Arrays.copyOfRange(array, index, statementLength + index)); 48 | index += statementLength; 49 | statementLength = array[index++]; 50 | this.challengeZero = new BigInteger(Arrays.copyOfRange(array, index, statementLength + index)); 51 | index += statementLength; 52 | statementLength = array[index++]; 53 | this.challengeOne = new BigInteger(Arrays.copyOfRange(array, index, statementLength + index)); 54 | index += statementLength; 55 | statementLength = array[index++]; 56 | this.responseS = new BigInteger(Arrays.copyOfRange(array, index, statementLength + index)); 57 | index += statementLength; 58 | statementLength = array[index++]; 59 | this.responseT = new BigInteger(Arrays.copyOfRange(array, index, statementLength + index)); 60 | index += statementLength; 61 | statementLength = array[index++]; 62 | this.responseV = new BigInteger(Arrays.copyOfRange(array, index, statementLength + index)); 63 | index += statementLength; 64 | statementLength = array[index++]; 65 | this.responseXHat = new BigInteger(Arrays.copyOfRange(array, index, statementLength + index)); 66 | index += statementLength; 67 | statementLength = array[index++]; 68 | this.responseZero = new BigInteger(Arrays.copyOfRange(array, index, statementLength + index)); 69 | index += statementLength; 70 | statementLength = array[index++]; 71 | this.responseOne = new BigInteger(Arrays.copyOfRange(array, index, statementLength + index)); 72 | } 73 | 74 | @Override 75 | public byte[] serialize() { 76 | byte[] commitmentBalanceEncoded = this.commitmentBalance.getEncoded(true); 77 | byte[] commitmentXHatEncoded = this.commitmentXHat.getEncoded(true); 78 | byte[] challengeZeroEncoded = this.challengeZero.toByteArray(); 79 | byte[] challengeOneEncoded = this.challengeOne.toByteArray(); 80 | 81 | byte[] responseSEncoded = this.responseS.toByteArray(); 82 | byte[] responseTEncoded = this.responseT.toByteArray(); 83 | byte[] responseVEncoded = this.responseV.toByteArray(); 84 | byte[] responseXHatEncoded = this.responseXHat.toByteArray(); 85 | byte[] responseZeroEncoded = this.responseZero.toByteArray(); 86 | byte[] responseOneEncoded = this.responseOne.toByteArray(); 87 | 88 | List arrList = Arrays.asList(commitmentBalanceEncoded, commitmentXHatEncoded, challengeZeroEncoded, challengeOneEncoded,responseSEncoded, responseTEncoded, responseVEncoded, responseXHatEncoded, responseZeroEncoded, responseOneEncoded); 89 | int totalLength = arrList.stream().mapToInt(arr -> arr.length).map(i -> i + 1).sum(); 90 | byte[] fullArray = new byte[totalLength]; 91 | int currIndex = 0; 92 | for (byte[] arr2 : arrList) { 93 | fullArray[currIndex++] = (byte) arr2.length; 94 | System.arraycopy(arr2, 0, fullArray, currIndex, arr2.length); 95 | currIndex += arr2.length; 96 | } 97 | return fullArray; 98 | } 99 | 100 | public BigInteger getChallengeZero() { 101 | return this.challengeZero; 102 | } 103 | 104 | public BigInteger getChallengeOne() { 105 | return challengeOne; 106 | } 107 | 108 | public BigInteger getResponseS() { 109 | return this.responseS; 110 | } 111 | 112 | public ECPoint getCommitmentBalance() { 113 | return this.commitmentBalance; 114 | } 115 | 116 | public ECPoint getCommitmentXHat() { 117 | return this.commitmentXHat; 118 | } 119 | 120 | public BigInteger getResponseV() { 121 | return this.responseV; 122 | } 123 | 124 | public BigInteger getResponseT() { 125 | return this.responseT; 126 | } 127 | 128 | public BigInteger getResponseXHat() { 129 | return this.responseXHat; 130 | } 131 | 132 | public BigInteger getResponseZero() { 133 | return responseZero; 134 | } 135 | 136 | public BigInteger getResponseOne() { 137 | return responseOne; 138 | } 139 | } 140 | 141 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/proof/assets/AddressProofData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.proof.assets; 5 | 6 | import edu.stanford.crypto.proof.ProofData; 7 | import org.bouncycastle.math.ec.ECPoint; 8 | 9 | import java.math.BigInteger; 10 | import java.util.Optional; 11 | 12 | class AddressProofData implements ProofData { 13 | private final ECPoint publicKey; 14 | private final BigInteger balance; 15 | private final Optional privateKey; 16 | private final BigInteger balanceRandomness; 17 | private final BigInteger keyKnownRandomness; 18 | private final ECPoint g; 19 | private final ECPoint h; 20 | 21 | public AddressProofData(BigInteger privateKey, ECPoint publicKey, BigInteger balance, BigInteger balanceRandomness, BigInteger keyKnownRandomness, ECPoint g, ECPoint h) { 22 | this.privateKey = Optional.of(privateKey); 23 | this.balanceRandomness = balanceRandomness; 24 | this.keyKnownRandomness = keyKnownRandomness; 25 | this.publicKey = publicKey; 26 | this.balance = balance; 27 | this.g = g; 28 | this.h = h; 29 | } 30 | 31 | public AddressProofData(Optional privateKey, ECPoint publicKey, BigInteger balance, BigInteger balanceRandomness, BigInteger keyKnownRandomness, ECPoint g, ECPoint h) { 32 | this.privateKey =privateKey; 33 | this.balanceRandomness = balanceRandomness; 34 | this.keyKnownRandomness = keyKnownRandomness; 35 | this.publicKey = publicKey; 36 | this.balance = balance; 37 | this.g = g; 38 | this.h = h; 39 | } 40 | 41 | 42 | 43 | public Optional getPrivateKey() { 44 | return this.privateKey; 45 | } 46 | 47 | public BigInteger getBalanceRandomness() { 48 | return this.balanceRandomness; 49 | } 50 | 51 | public BigInteger getKeyKnownRandomness() { 52 | return this.keyKnownRandomness; 53 | } 54 | 55 | public ECPoint getPublicKey() { 56 | return this.publicKey; 57 | } 58 | 59 | public BigInteger getBalance() { 60 | return this.balance; 61 | } 62 | 63 | public ECPoint getG() { 64 | return this.g; 65 | } 66 | 67 | public ECPoint getH() { 68 | return this.h; 69 | } 70 | } 71 | 72 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/proof/assets/AddressProofEntry.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.proof.assets; 5 | 6 | import edu.stanford.crypto.proof.binary.BinaryProof; 7 | import org.bouncycastle.math.ec.ECPoint; 8 | 9 | public class AddressProofEntry { 10 | private final ECPoint publicKey; 11 | private final AddressProof addressProof; 12 | 13 | public AddressProofEntry(ECPoint publicKey, AddressProof addressProof) { 14 | this.publicKey = publicKey; 15 | this.addressProof = addressProof; 16 | } 17 | 18 | public ECPoint getPublicKey() { 19 | return this.publicKey; 20 | } 21 | 22 | public AddressProof getAddressProof() { 23 | return this.addressProof; 24 | } 25 | 26 | } 27 | 28 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/proof/assets/AddressProofSystem.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.proof.assets; 5 | 6 | import edu.stanford.crypto.ECConstants; 7 | import edu.stanford.crypto.ProofUtils; 8 | import edu.stanford.crypto.proof.ProofSystem; 9 | import org.bouncycastle.math.ec.ECPoint; 10 | 11 | import java.math.BigInteger; 12 | import java.util.Optional; 13 | 14 | /** 15 | * Zero knowledge proof for public key y with balance b of the statement:
16 | * "Either I know the private key x such that xG=y and p is a commitment to b or p is a commitment to 0." 17 | */ 18 | public class AddressProofSystem implements ProofSystem { 19 | @Override 20 | public AddressProof createProof(AddressProofData data) { 21 | BigInteger u1 = ProofUtils.randomNumber(); 22 | BigInteger u2 = ProofUtils.randomNumber(); 23 | BigInteger u3 = ProofUtils.randomNumber(); 24 | BigInteger u4 = ProofUtils.randomNumber(); 25 | ECPoint g = data.getG(); 26 | ECPoint h = data.getH(); 27 | ECPoint y = data.getPublicKey(); 28 | ECPoint b = data.getG().multiply(data.getBalance()); 29 | ECPoint a1 = b.multiply(u1).add(h.multiply(u2)); 30 | ECPoint a2 = y.multiply(u1).add(h.multiply(u3)); 31 | ECPoint a3 = g.multiply(u4).add(h.multiply(u3)); 32 | Optional privateKey = data.getPrivateKey(); 33 | BigInteger v = data.getBalanceRandomness(); 34 | BigInteger t = data.getKeyKnownRandomness(); 35 | BigInteger s = privateKey.isPresent() ? BigInteger.ONE : BigInteger.ZERO; 36 | ECPoint p = b.multiply(s).add(h.multiply(v)); 37 | ECPoint l = y.multiply(s).add(h.multiply(t)); 38 | 39 | //Binary proof 40 | BigInteger uZero = ProofUtils.randomNumber(); 41 | BigInteger uOne = ProofUtils.randomNumber(); 42 | BigInteger falseChallenge = ProofUtils.randomNumber(256).mod(ECConstants.CHALLENGE_Q); 43 | ECPoint falseChallengeElement = b.multiply(falseChallenge); 44 | ECPoint aZero = h.multiply(uZero).subtract(falseChallengeElement.multiply(s)); 45 | ECPoint aOne = h.multiply(uOne).add(falseChallengeElement.multiply(BigInteger.ONE.subtract(s))); 46 | 47 | 48 | BigInteger challenge = ProofUtils.computeChallenge(g, h, y, b, p, l, a1, a2, a3, aZero, aOne); 49 | BigInteger responseS = u1.add(challenge.multiply(s)); 50 | BigInteger responseV = u2.add(challenge.multiply(v)); 51 | BigInteger responseT = u3.add(challenge.multiply(t)); 52 | BigInteger responseX = u4.add(challenge.multiply(privateKey.orElse(BigInteger.ZERO))); 53 | BigInteger trueChallenge = challenge.subtract(falseChallenge).mod(ECConstants.CHALLENGE_Q); 54 | BigInteger falseV = falseChallenge.multiply(v); 55 | BigInteger trueV = trueChallenge.multiply(v); 56 | 57 | BigInteger responseZero = uZero.add(trueV.multiply(BigInteger.ONE.subtract(s))).add(falseV.multiply(s)).mod(ECConstants.Q); 58 | BigInteger responseOne = uOne.add(falseV.multiply(BigInteger.ONE.subtract(s))).add(trueV.multiply(s)).mod(ECConstants.Q); 59 | 60 | 61 | return new AddressProof(p, l, privateKey.isPresent() ? falseChallenge : trueChallenge, privateKey.isPresent() ? trueChallenge : falseChallenge, responseS, responseV, responseT, responseX, responseZero, responseOne); 62 | } 63 | 64 | } 65 | 66 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/proof/assets/AssetProof.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.proof.assets; 5 | 6 | import edu.stanford.crypto.ECConstants; 7 | import edu.stanford.crypto.SQLDatabase; 8 | import edu.stanford.crypto.database.Database; 9 | import edu.stanford.crypto.proof.Proof; 10 | import edu.stanford.crypto.proof.binary.BinaryProof; 11 | import org.bouncycastle.math.ec.ECPoint; 12 | 13 | import java.sql.Connection; 14 | import java.sql.PreparedStatement; 15 | import java.sql.ResultSet; 16 | import java.sql.SQLException; 17 | import java.util.Iterator; 18 | 19 | public class AssetProof 20 | implements Proof, 21 | SQLDatabase { 22 | public static final String ADD_ADDRESS = "INSERT INTO asset_proof VALUES (?, ?) "; 23 | public static final String GET_PROOF_SQL = "SELECT asset_proof.main_proof FROM asset_proof WHERE public_key= ?"; 24 | public static final String LIST_PROOFS_SQL = "SELECT asset_proof.public_key,asset_proof.main_proof FROM asset_proof "; 25 | public static final String READ_SIZE = "SELECT pg_size_pretty(pg_total_relation_size('public.asset_proof'))"; 26 | private final PreparedStatement updateStatement; 27 | private final PreparedStatement readStatement; 28 | private final Connection connection = Database.getConnection(); 29 | 30 | public AssetProof() throws SQLException { 31 | this.updateStatement = this.connection.prepareStatement(ADD_ADDRESS); 32 | this.readStatement = this.connection.prepareStatement(GET_PROOF_SQL); 33 | } 34 | 35 | @Override 36 | public void close() throws SQLException { 37 | this.connection.close(); 38 | } 39 | 40 | public void addAddressProof(ECPoint publicKey, AddressProof proof) { 41 | try { 42 | this.updateStatement.setBytes(1, publicKey.getEncoded(true)); 43 | this.updateStatement.setBytes(2, proof.serialize()); 44 | this.updateStatement.executeUpdate(); 45 | } 46 | catch (SQLException ex) { 47 | throw new IllegalArgumentException(ex); 48 | } 49 | } 50 | 51 | public AddressProof getAddressProof(ECPoint publicKey) { 52 | try { 53 | this.readStatement.setBytes(1, publicKey.getEncoded(true)); 54 | ResultSet resultSet = this.readStatement.executeQuery(); 55 | if (resultSet.next()) { 56 | byte[] proof = resultSet.getBytes(1); 57 | return new AddressProof(proof); 58 | } 59 | } 60 | catch (SQLException ex) { 61 | ex.printStackTrace(); 62 | } 63 | throw new IllegalArgumentException("No such id " + publicKey.normalize()); 64 | } 65 | 66 | public Iterator getAddressProofs() { 67 | try { 68 | this.connection.setAutoCommit(false); 69 | final ResultSet resultSet = this.connection.createStatement().executeQuery(LIST_PROOFS_SQL); 70 | resultSet.setFetchSize(1000); 71 | return new Iterator(){ 72 | 73 | @Override 74 | public boolean hasNext() { 75 | try { 76 | boolean next = resultSet.next(); 77 | if (!next) { 78 | AssetProof.this.connection.setAutoCommit(true); 79 | } 80 | return next; 81 | } 82 | catch (SQLException e) { 83 | e.printStackTrace(); 84 | throw new IllegalStateException(e); 85 | } 86 | } 87 | 88 | @Override 89 | public AddressProofEntry next() { 90 | try { 91 | byte[] publicKeyBytes = resultSet.getBytes(1); 92 | byte[] proofBytes = resultSet.getBytes(2); 93 | ECPoint publicKey = ECConstants.BITCOIN_CURVE.decodePoint(publicKeyBytes); 94 | AddressProof addressProof = new AddressProof(proofBytes); 95 | return new AddressProofEntry(publicKey, addressProof); 96 | } 97 | catch (SQLException e) { 98 | e.printStackTrace(); 99 | throw new IllegalStateException(e); 100 | } 101 | } 102 | }; 103 | } 104 | catch (SQLException e) { 105 | e.printStackTrace(); 106 | throw new IllegalStateException(e); 107 | } 108 | } 109 | 110 | public Connection getConnection() { 111 | return this.connection; 112 | } 113 | 114 | public String getSizeInfo() { 115 | try { 116 | ResultSet resultSet = this.connection.createStatement().executeQuery(READ_SIZE); 117 | if (resultSet.next()) { 118 | return resultSet.getString(1); 119 | } 120 | } 121 | catch (SQLException e) { 122 | e.printStackTrace(); 123 | } 124 | throw new IllegalStateException("Couldn't run query "+READ_SIZE); 125 | } 126 | 127 | } 128 | 129 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/proof/assets/AssetProofData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.proof.assets; 5 | 6 | import edu.stanford.crypto.proof.ProofData; 7 | 8 | public class AssetProofData implements ProofData { 9 | } 10 | 11 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/proof/assets/AssetProofSystem.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.proof.assets; 5 | 6 | import edu.stanford.crypto.ECConstants; 7 | import edu.stanford.crypto.ProofUtils; 8 | import edu.stanford.crypto.bitcoin.BlockchainEntry; 9 | import edu.stanford.crypto.bitcoin.PrivateKeyDatabase; 10 | import edu.stanford.crypto.bitcoin.SQLBlockchain; 11 | import edu.stanford.crypto.bitcoin.SQLPrivateKeyDatabase; 12 | import edu.stanford.crypto.proof.ProofSystem; 13 | import edu.stanford.crypto.proof.binary.BinaryProof; 14 | import edu.stanford.crypto.proof.binary.BinaryProofData; 15 | import edu.stanford.crypto.proof.binary.BinaryProofSystem; 16 | import org.apache.logging.log4j.LogManager; 17 | import org.apache.logging.log4j.Logger; 18 | import org.apache.logging.log4j.Marker; 19 | import org.bouncycastle.math.ec.ECPoint; 20 | 21 | import java.math.BigInteger; 22 | import java.sql.SQLException; 23 | import java.util.Iterator; 24 | import java.util.Optional; 25 | import java.util.concurrent.*; 26 | import java.util.stream.Stream; 27 | 28 | public class AssetProofSystem 29 | implements ProofSystem { 30 | private static final Logger LOGGER = LogManager.getLogger(); 31 | private final AddressProofSystem addressProofSystem = new AddressProofSystem(); 32 | private final BlockingQueue blockchainEntriesQueue = new ArrayBlockingQueue<>(Runtime.getRuntime().availableProcessors() * 3); 33 | private final BinaryProofSystem binaryProofSystem = new BinaryProofSystem(); 34 | 35 | /* 36 | * Enabled aggressive block sorting 37 | * Enabled unnecessary exception pruning 38 | * Enabled aggressive exception aggregation 39 | */ 40 | @Override 41 | public AssetProof createProof(AssetProofData data) { 42 | try { 43 | SQLBlockchain blockchain = new SQLBlockchain(); 44 | SQLPrivateKeyDatabase privateKeyDatabase = new SQLPrivateKeyDatabase(); 45 | try { 46 | AssetProof proof; 47 | ExecutorService executorService; 48 | Iterator blockchainEntries = blockchain.getBlockchainEntries(); 49 | proof = new AssetProof(); 50 | int nThreads = Runtime.getRuntime().availableProcessors() - 1; 51 | executorService = Executors.newFixedThreadPool(nThreads); 52 | proof.getConnection().setAutoCommit(false); 53 | Stream.generate(AddressProofWorkerThread::new).limit(nThreads).forEach(executorService::submit); 54 | BlockchainEntry blockchainEntry; 55 | while (blockchainEntries.hasNext()) { 56 | blockchainEntry = blockchainEntries.next(); 57 | if (this.blockchainEntriesQueue.offer(blockchainEntry)) continue; 58 | this.createAddressProof(blockchainEntry, proof, privateKeyDatabase); 59 | } 60 | while ((blockchainEntry = this.blockchainEntriesQueue.poll()) != null) { 61 | this.createAddressProof(blockchainEntry, proof, privateKeyDatabase); 62 | } 63 | 64 | executorService.shutdownNow(); 65 | executorService.awaitTermination(1, TimeUnit.MINUTES); 66 | proof.getConnection().setAutoCommit(true); 67 | return proof; 68 | } finally { 69 | privateKeyDatabase.close(); 70 | blockchain.close(); 71 | } 72 | } catch (SQLException | InterruptedException e) { 73 | LOGGER.error("Exception while running asset proof", e); 74 | throw new IllegalArgumentException("Couldn't complete proof"); 75 | } 76 | } 77 | 78 | private void createAddressProof(BlockchainEntry blockchainEntry, AssetProof proof, PrivateKeyDatabase privateKeyDatabase) { 79 | BigInteger balanceRandomness = ProofUtils.randomNumber(); 80 | BigInteger keyKnownRandomness = ProofUtils.randomNumber(); 81 | ECPoint pubKey = blockchainEntry.getPubKey(); 82 | Optional privateKey = privateKeyDatabase.retrievePrivateKey(pubKey); 83 | AddressProofData addressProofData = new AddressProofData(privateKey, pubKey, blockchainEntry.getBalance(), balanceRandomness, keyKnownRandomness, ECConstants.G, ECConstants.H); 84 | AddressProof addressProof = this.addressProofSystem.createProof(addressProofData); 85 | 86 | proof.addAddressProof(pubKey, addressProof); 87 | } 88 | 89 | private class AddressProofWorkerThread 90 | implements Runnable { 91 | private AddressProofWorkerThread() { 92 | } 93 | 94 | @Override 95 | public void run() { 96 | try (AssetProof assetProof = new AssetProof()) { 97 | try (SQLPrivateKeyDatabase database = new SQLPrivateKeyDatabase()) { 98 | while (!Thread.interrupted()) { 99 | try { 100 | BlockchainEntry entry = AssetProofSystem.this.blockchainEntriesQueue.take(); 101 | AssetProofSystem.this.createAddressProof(entry, assetProof, database); 102 | } catch (InterruptedException e) { 103 | // empty catch block 104 | break; 105 | } 106 | } 107 | 108 | 109 | } 110 | } catch (SQLException e) { 111 | e.printStackTrace(); 112 | throw new RuntimeException(e); 113 | } 114 | } 115 | } 116 | 117 | } 118 | 119 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/proof/balance/BalanceProof.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.proof.balance; 5 | 6 | import com.sun.org.apache.regexp.internal.RE; 7 | import edu.stanford.crypto.SQLDatabase; 8 | import edu.stanford.crypto.database.Database; 9 | import edu.stanford.crypto.proof.Proof; 10 | import edu.stanford.crypto.proof.binary.BinaryRangeProof; 11 | 12 | import java.math.BigInteger; 13 | import java.sql.Connection; 14 | import java.sql.PreparedStatement; 15 | import java.sql.ResultSet; 16 | import java.sql.SQLException; 17 | import java.util.Arrays; 18 | import java.util.Iterator; 19 | 20 | public class BalanceProof 21 | implements Proof, 22 | SQLDatabase { 23 | public static final String ADD_USER_SQL = "INSERT INTO balance_proof VALUES (?, ?) "; 24 | public static final String GET_PROOF_SQL = "SELECT balance_proof.range_proof FROM balance_proof WHERE customer_id_hash= ?"; 25 | public static final String LIST_PROOFS_SQL = "SELECT balance_proof.range_proof FROM balance_proof "; 26 | public static final String READ_SIZE = "SELECT pg_size_pretty(pg_total_relation_size('public.balance_proof'))"; 27 | private final PreparedStatement updateStatement; 28 | private final PreparedStatement readStatement; 29 | private final Connection connection = Database.getConnection(); 30 | 31 | public BalanceProof() throws SQLException { 32 | this.updateStatement = this.connection.prepareStatement(ADD_USER_SQL); 33 | this.readStatement = this.connection.prepareStatement(GET_PROOF_SQL); 34 | } 35 | 36 | public void addCustomer(BigInteger hashedId, BinaryRangeProof balanceProof) { 37 | try { 38 | this.updateStatement.setBytes(1, hashedId.toByteArray()); 39 | this.updateStatement.setBytes(2, balanceProof.serialize()); 40 | this.updateStatement.executeUpdate(); 41 | } catch (SQLException ex) { 42 | throw new IllegalArgumentException(ex); 43 | } 44 | } 45 | 46 | public BinaryRangeProof getCustomerProof(BigInteger hashedId) { 47 | try { 48 | this.readStatement.setBytes(1, hashedId.toByteArray()); 49 | ResultSet resultSet = this.readStatement.executeQuery(); 50 | if (resultSet.next()) { 51 | byte[] proof = resultSet.getBytes(1); 52 | return new BinaryRangeProof(proof); 53 | } 54 | } catch (SQLException ex) { 55 | ex.printStackTrace(); 56 | } 57 | throw new IllegalArgumentException("No such id " + Arrays.toString(hashedId.toByteArray())); 58 | } 59 | 60 | public Iterator getRangeProofs() { 61 | try { 62 | this.connection.setAutoCommit(false); 63 | final ResultSet resultSet = this.connection.createStatement().executeQuery(LIST_PROOFS_SQL); 64 | resultSet.setFetchSize(1000); 65 | return new Iterator() { 66 | 67 | @Override 68 | public boolean hasNext() { 69 | try { 70 | boolean next = resultSet.next(); 71 | if (!next) { 72 | BalanceProof.this.connection.setAutoCommit(true); 73 | } 74 | return next; 75 | } catch (SQLException e) { 76 | e.printStackTrace(); 77 | throw new IllegalStateException(e); 78 | } 79 | } 80 | 81 | @Override 82 | public BinaryRangeProof next() { 83 | try { 84 | byte[] bytes = resultSet.getBytes(1); 85 | return new BinaryRangeProof(bytes); 86 | } catch (SQLException e) { 87 | e.printStackTrace(); 88 | throw new IllegalStateException(e); 89 | } 90 | } 91 | }; 92 | } catch (SQLException e) { 93 | e.printStackTrace(); 94 | throw new IllegalStateException(e); 95 | } 96 | } 97 | 98 | public String getSizeInfo() { 99 | try { 100 | ResultSet resultSet = this.connection.createStatement().executeQuery(READ_SIZE); 101 | if (resultSet.next()) { 102 | return resultSet.getString(1); 103 | } 104 | } catch (SQLException e) { 105 | e.printStackTrace(); 106 | } 107 | throw new IllegalStateException("Couldn't run query " + READ_SIZE); 108 | } 109 | 110 | @Override 111 | public void close() throws SQLException { 112 | this.connection.close(); 113 | } 114 | 115 | public Connection getConnection() { 116 | return this.connection; 117 | } 118 | 119 | } 120 | 121 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/proof/balance/BalanceProofData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.proof.balance; 5 | 6 | import edu.stanford.crypto.proof.ProofData; 7 | 8 | public class BalanceProofData 9 | implements ProofData { 10 | private final int maxBits; 11 | 12 | public BalanceProofData(int maxBits) { 13 | this.maxBits = maxBits; 14 | } 15 | 16 | public int getMaxBits() { 17 | return this.maxBits; 18 | } 19 | } 20 | 21 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/proof/balance/BalanceProofSystem.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.proof.balance; 5 | 6 | import edu.stanford.crypto.ProofUtils; 7 | import edu.stanford.crypto.bitcoin.CustomerSecretsDatabase; 8 | import edu.stanford.crypto.bitcoin.SQLCustomerDatabase; 9 | import edu.stanford.crypto.bitcoin.SQLCustomerSecretsDatabase; 10 | import edu.stanford.crypto.proof.ProofSystem; 11 | import edu.stanford.crypto.proof.RangeProofData; 12 | import edu.stanford.crypto.proof.binary.BinaryRangeProof; 13 | import edu.stanford.crypto.proof.rangeproof.BinaryRangeProofSystem; 14 | 15 | import java.math.BigInteger; 16 | import java.sql.SQLException; 17 | import java.util.Iterator; 18 | import java.util.List; 19 | import java.util.concurrent.*; 20 | import java.util.concurrent.atomic.AtomicReference; 21 | import java.util.stream.Collectors; 22 | import java.util.stream.Stream; 23 | 24 | public class BalanceProofSystem 25 | implements ProofSystem { 26 | private final BinaryRangeProofSystem rangeProofSystem = new BinaryRangeProofSystem(); 27 | private final BlockingQueue customerInfos = new ArrayBlockingQueue(Runtime.getRuntime().availableProcessors() * 3); 28 | private final AtomicReference balanceKey = new AtomicReference(BigInteger.ZERO); 29 | 30 | /* 31 | * Enabled aggressive block sorting 32 | * Enabled unnecessary exception pruning 33 | * Enabled aggressive exception aggregation 34 | */ 35 | @Override 36 | public BalanceProof createProof(BalanceProofData data) { 37 | try (SQLCustomerDatabase customerSecretsDatabase = new SQLCustomerDatabase()) { 38 | BalanceProof proof; 39 | ExecutorService executorService; 40 | Iterator customerInfoIterator = customerSecretsDatabase.getCustomers(); 41 | proof = new BalanceProof(); 42 | int nThreads = Runtime.getRuntime().availableProcessors() - 1; 43 | executorService = Executors.newFixedThreadPool(nThreads); 44 | proof.getConnection().setAutoCommit(false); 45 | Stream.generate(() -> new RangeProofWorkerThread(data.getMaxBits())).limit(nThreads).forEach(executorService::submit); 46 | try (SQLCustomerSecretsDatabase database2 = new SQLCustomerSecretsDatabase()) { 47 | CustomerInfo info; 48 | while (customerInfoIterator.hasNext()) { 49 | CustomerInfo customerInfo = customerInfoIterator.next(); 50 | if (this.customerInfos.offer(customerInfo)) continue; 51 | this.createRangeProof(customerInfo, proof, database2, data.getMaxBits()); 52 | } 53 | while ((info = this.customerInfos.poll()) != null) { 54 | this.createRangeProof(info, proof, database2, data.getMaxBits()); 55 | } 56 | } 57 | executorService.shutdownNow(); 58 | executorService.awaitTermination(1, TimeUnit.MINUTES); 59 | proof.getConnection().setAutoCommit(true); 60 | return proof; 61 | 62 | } catch (SQLException e) { 63 | e.printStackTrace(); 64 | throw new IllegalArgumentException("Couldn't complete proof"); 65 | } catch (InterruptedException e) { 66 | e.printStackTrace(); 67 | } 68 | throw new IllegalArgumentException("Couldn't complete proof"); 69 | } 70 | 71 | public BigInteger getBalanceKey() { 72 | return this.balanceKey.get(); 73 | } 74 | 75 | private void createRangeProof(CustomerInfo customerInfo, BalanceProof proof, CustomerSecretsDatabase database, int maxBits) { 76 | List randomness = Stream.generate(ProofUtils::randomNumber).limit(maxBits).collect(Collectors.toList()); 77 | BigInteger totalRandomness = BigInteger.ZERO; 78 | for (int i = 0; i < randomness.size(); ++i) { 79 | totalRandomness = totalRandomness.add(randomness.get(i).shiftLeft(i)); 80 | } 81 | this.balanceKey.accumulateAndGet(totalRandomness, BigInteger::add); 82 | RangeProofData rangeProofData = new RangeProofData(customerInfo.getBalance(), randomness); 83 | BinaryRangeProof rangeProof = this.rangeProofSystem.createProof(rangeProofData); 84 | BigInteger hashSalt = ProofUtils.randomNumber(); 85 | BigInteger hashedId = ProofUtils.hash(customerInfo.getId(), hashSalt); 86 | proof.addCustomer(hashedId, rangeProof); 87 | database.store(customerInfo.getId(), hashSalt, rangeProofData.getTotalRandomness()); 88 | } 89 | 90 | private class RangeProofWorkerThread 91 | implements Runnable { 92 | private final int maxBits; 93 | 94 | private RangeProofWorkerThread(int maxBits) { 95 | this.maxBits = maxBits; 96 | } 97 | 98 | @Override 99 | public void run() { 100 | try (BalanceProof balanceProof = new BalanceProof()) { 101 | try (SQLCustomerSecretsDatabase database = new SQLCustomerSecretsDatabase()) { 102 | 103 | while (!Thread.interrupted()) { 104 | try { 105 | CustomerInfo info = BalanceProofSystem.this.customerInfos.take(); 106 | BalanceProofSystem.this.createRangeProof(info, balanceProof, database, this.maxBits); 107 | } catch (InterruptedException e) { 108 | // empty catch block 109 | break; 110 | } 111 | } 112 | 113 | } 114 | } catch (SQLException e) { 115 | e.printStackTrace(); 116 | } 117 | } 118 | } 119 | 120 | } 121 | 122 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/proof/balance/CustomerInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.proof.balance; 5 | 6 | import java.math.BigInteger; 7 | 8 | public class CustomerInfo { 9 | private final String id; 10 | private final BigInteger balance; 11 | 12 | public CustomerInfo(String id, BigInteger balance) { 13 | this.id = id; 14 | this.balance = balance; 15 | } 16 | 17 | public String getId() { 18 | return this.id; 19 | } 20 | 21 | public BigInteger getBalance() { 22 | return this.balance; 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/proof/balance/CustomerSecrets.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.proof.balance; 5 | 6 | import java.math.BigInteger; 7 | 8 | public class CustomerSecrets { 9 | private final BigInteger hashSalt; 10 | private final BigInteger combinedRandomness; 11 | 12 | public CustomerSecrets(BigInteger hashSalt, BigInteger combinedRandomness) { 13 | this.hashSalt = hashSalt; 14 | this.combinedRandomness = combinedRandomness; 15 | } 16 | 17 | public BigInteger getHashSalt() { 18 | return this.hashSalt; 19 | } 20 | 21 | public BigInteger getCombinedRandomness() { 22 | return this.combinedRandomness; 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/proof/binary/BinaryProof.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.proof.binary; 5 | 6 | import edu.stanford.crypto.ECConstants; 7 | import edu.stanford.crypto.proof.MemoryProof; 8 | import org.bouncycastle.math.ec.ECPoint; 9 | 10 | import java.math.BigInteger; 11 | import java.util.Arrays; 12 | import java.util.List; 13 | 14 | public class BinaryProof 15 | implements MemoryProof { 16 | private final ECPoint statement; 17 | private final BigInteger challengeZero; 18 | private final BigInteger challengeOne; 19 | private final BigInteger responseZero; 20 | private final BigInteger responseOne; 21 | 22 | public BinaryProof(ECPoint statement, BigInteger challengeZero, BigInteger challengeOne, BigInteger responseZero, BigInteger responseOne) { 23 | this.statement = statement; 24 | this.challengeZero = challengeZero; 25 | this.challengeOne = challengeOne; 26 | this.responseZero = responseZero; 27 | this.responseOne = responseOne; 28 | } 29 | 30 | public BinaryProof(byte[] array) { 31 | this(array, new int[]{0}); 32 | } 33 | 34 | public BinaryProof(byte[] array, int[] index) { 35 | int n = index[0]; 36 | index[0] = n + 1; 37 | byte statementLength = array[n]; 38 | this.statement = ECConstants.BITCOIN_CURVE.decodePoint(Arrays.copyOfRange(array, index[0], statementLength + index[0])); 39 | index[0] = index[0] + statementLength; 40 | int n2 = index[0]; 41 | index[0] = n2 + 1; 42 | statementLength = array[n2]; 43 | this.challengeZero = new BigInteger(Arrays.copyOfRange(array, index[0], statementLength + index[0])); 44 | index[0] = index[0] + statementLength; 45 | int n3 = index[0]; 46 | index[0] = n3 + 1; 47 | statementLength = array[n3]; 48 | this.challengeOne = new BigInteger(Arrays.copyOfRange(array, index[0], statementLength + index[0])); 49 | index[0] = index[0] + statementLength; 50 | int n4 = index[0]; 51 | index[0] = n4 + 1; 52 | statementLength = array[n4]; 53 | this.responseZero = new BigInteger(Arrays.copyOfRange(array, index[0], statementLength + index[0])); 54 | index[0] = index[0] + statementLength; 55 | int n5 = index[0]; 56 | index[0] = n5 + 1; 57 | statementLength = array[n5]; 58 | this.responseOne = new BigInteger(Arrays.copyOfRange(array, index[0], statementLength + index[0])); 59 | index[0] = index[0] + statementLength; 60 | } 61 | 62 | public ECPoint getStatement() { 63 | return this.statement; 64 | } 65 | 66 | public BigInteger getChallengeZero() { 67 | return this.challengeZero; 68 | } 69 | 70 | public BigInteger getChallengeOne() { 71 | return this.challengeOne; 72 | } 73 | 74 | public BigInteger getResponseZero() { 75 | return this.responseZero; 76 | } 77 | 78 | public BigInteger getResponseOne() { 79 | return this.responseOne; 80 | } 81 | 82 | @Override 83 | public byte[] serialize() { 84 | byte[] encodedStatement = this.statement.getEncoded(true); 85 | byte[] chall0Arr = this.challengeZero.toByteArray(); 86 | byte[] challOneArr = this.challengeOne.toByteArray(); 87 | byte[] responseZeroArr = this.responseZero.toByteArray(); 88 | byte[] responseOneArr = this.responseOne.toByteArray(); 89 | List arrList = Arrays.asList(encodedStatement, chall0Arr, challOneArr, responseZeroArr, responseOneArr); 90 | int totalLength = arrList.stream().mapToInt(arr -> arr.length).map(i -> i + 1).sum(); 91 | byte[] fullArray = new byte[totalLength]; 92 | int currIndex = 0; 93 | for (byte[] arr2 : arrList) { 94 | fullArray[currIndex++] = (byte)arr2.length; 95 | System.arraycopy(arr2, 0, fullArray, currIndex, arr2.length); 96 | currIndex += arr2.length; 97 | } 98 | return fullArray; 99 | } 100 | } 101 | 102 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/proof/binary/BinaryProofData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.proof.binary; 5 | 6 | import edu.stanford.crypto.proof.ProofData; 7 | import org.bouncycastle.math.ec.ECPoint; 8 | 9 | import java.math.BigInteger; 10 | 11 | public class BinaryProofData 12 | implements ProofData { 13 | private final boolean secret; 14 | private final ECPoint g; 15 | private final ECPoint h; 16 | private final BigInteger randomness; 17 | 18 | public BinaryProofData(boolean secret, ECPoint g, ECPoint h, BigInteger randomness) { 19 | this.secret = secret; 20 | this.g = g; 21 | this.h = h; 22 | this.randomness = randomness; 23 | } 24 | 25 | public boolean getSecret() { 26 | return this.secret; 27 | } 28 | 29 | public ECPoint getG() { 30 | return this.g; 31 | } 32 | 33 | public ECPoint getH() { 34 | return this.h; 35 | } 36 | 37 | public BigInteger getRandomness() { 38 | return this.randomness; 39 | } 40 | } 41 | 42 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/proof/binary/BinaryProofSystem.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.proof.binary; 5 | 6 | import edu.stanford.crypto.ECConstants; 7 | import edu.stanford.crypto.ProofUtils; 8 | import edu.stanford.crypto.proof.ProofSystem; 9 | import org.bouncycastle.math.ec.ECPoint; 10 | 11 | import java.math.BigInteger; 12 | 13 | public class BinaryProofSystem 14 | implements ProofSystem { 15 | @Override 16 | public BinaryProof createProof(BinaryProofData data) { 17 | BinaryProof proof; 18 | BigInteger falseChallenge = ProofUtils.randomNumber(256).mod(ECConstants.CHALLENGE_Q); 19 | BigInteger u0 = ProofUtils.randomNumber(); 20 | BigInteger u1 = ProofUtils.randomNumber(); 21 | ECPoint h = data.getH(); 22 | ECPoint a0 = h.multiply(u0); 23 | ECPoint a1 = h.multiply(u1); 24 | BigInteger randomness = data.getRandomness(); 25 | ECPoint statement = h.multiply(randomness); 26 | ECPoint g = data.getG(); 27 | if (data.getSecret()) { 28 | statement = statement.add(g); 29 | a0 = a0.add(g.multiply(falseChallenge.negate())); 30 | } else { 31 | a1 = a1.add(g.multiply(falseChallenge)); 32 | } 33 | BigInteger challenge = ProofUtils.computeChallenge(g, h, statement, a0, a1); 34 | BigInteger trueChallenge = challenge.subtract(falseChallenge).mod(ECConstants.CHALLENGE_Q); 35 | if (data.getSecret()) { 36 | BigInteger responseZero = u0.add(falseChallenge.multiply(randomness)).mod(ECConstants.Q); 37 | BigInteger responseOne = u1.add(trueChallenge.multiply(randomness)).mod(ECConstants.Q); 38 | proof = new BinaryProof(statement, falseChallenge, trueChallenge, responseZero, responseOne); 39 | } else { 40 | BigInteger responseZero = u0.add(trueChallenge.multiply(randomness)).mod(ECConstants.Q); 41 | BigInteger responseOne = u1.add(falseChallenge.multiply(randomness)).mod(ECConstants.Q); 42 | proof = new BinaryProof(statement, trueChallenge, falseChallenge, responseZero, responseOne); 43 | } 44 | return proof; 45 | } 46 | } 47 | 48 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/proof/binary/BinaryRangeProof.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.proof.binary; 5 | 6 | import edu.stanford.crypto.ECConstants; 7 | import edu.stanford.crypto.proof.RangeProof; 8 | import org.bouncycastle.math.ec.ECPoint; 9 | 10 | import java.math.BigInteger; 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | import java.util.stream.Collectors; 14 | 15 | public class BinaryRangeProof 16 | implements RangeProof { 17 | private final List binaryProofList; 18 | 19 | @Override 20 | public byte[] serialize() { 21 | List bitSerializations = this.binaryProofList.stream().map(BinaryProof::serialize).collect(Collectors.toList()); 22 | byte[] serialization = new byte[bitSerializations.stream().mapToInt(arr -> arr.length).sum()]; 23 | int index = 0; 24 | for (byte[] arr2 : bitSerializations) { 25 | System.arraycopy(arr2, 0, serialization, index, arr2.length); 26 | index += arr2.length; 27 | } 28 | return serialization; 29 | } 30 | 31 | public BinaryRangeProof(List binaryProofList) { 32 | this.binaryProofList = binaryProofList; 33 | } 34 | 35 | public BinaryRangeProof(byte[] serialization) { 36 | int[] index = new int[]{0}; 37 | ArrayList bits = new ArrayList<>(); 38 | while (index[0] < serialization.length) { 39 | bits.add(new BinaryProof(serialization, index)); 40 | } 41 | this.binaryProofList = bits; 42 | } 43 | 44 | @Override 45 | public BigInteger getRange() { 46 | return BigInteger.ONE.shiftLeft(this.binaryProofList.size()).subtract(BigInteger.ONE); 47 | } 48 | 49 | public List getBitProofs() { 50 | return this.binaryProofList; 51 | } 52 | 53 | @Override 54 | public ECPoint getStatement() { 55 | ECPoint statement = ECConstants.INFINITY; 56 | for (int i = 0; i < this.binaryProofList.size(); ++i) { 57 | statement = statement.add(this.binaryProofList.get(i).getStatement().timesPow2(i)); 58 | } 59 | return statement; 60 | } 61 | } 62 | 63 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/proof/rangeproof/BinaryRangeProofSystem.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.proof.rangeproof; 5 | 6 | import edu.stanford.crypto.ECConstants; 7 | import edu.stanford.crypto.proof.ProofSystem; 8 | import edu.stanford.crypto.proof.RangeProofData; 9 | import edu.stanford.crypto.proof.binary.BinaryProof; 10 | import edu.stanford.crypto.proof.binary.BinaryProofData; 11 | import edu.stanford.crypto.proof.binary.BinaryProofSystem; 12 | import edu.stanford.crypto.proof.binary.BinaryRangeProof; 13 | 14 | import java.math.BigInteger; 15 | import java.util.ArrayList; 16 | 17 | public class BinaryRangeProofSystem 18 | implements ProofSystem { 19 | private final BinaryProofSystem bitsProver = new BinaryProofSystem(); 20 | 21 | @Override 22 | public BinaryRangeProof createProof(RangeProofData data) { 23 | BigInteger secret = data.getSecret(); 24 | ArrayList binaryProofList = new ArrayList<>(data.getRandomnes().size()); 25 | for (int i = 0; i < data.getRandomnes().size(); ++i) { 26 | BinaryProofData binaryProofData = new BinaryProofData(secret.testBit(i), ECConstants.G, ECConstants.H, data.getRandomnes().get(i)); 27 | binaryProofList.add(this.bitsProver.createProof(binaryProofData)); 28 | } 29 | return new BinaryRangeProof(binaryProofList); 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/verification/AddressProofVerifier.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.verification; 5 | 6 | import edu.stanford.crypto.ProofUtils; 7 | import edu.stanford.crypto.proof.assets.AddressProof; 8 | import org.bouncycastle.math.ec.ECPoint; 9 | 10 | import java.math.BigInteger; 11 | 12 | public class AddressProofVerifier 13 | implements Verifier { 14 | @Override 15 | public void verify(AddressProof proof, AddressVerificationData data) { 16 | ECPoint g = data.getG(); 17 | ECPoint h = data.getH(); 18 | ECPoint b = g.multiply(data.getBalance()); 19 | BigInteger transmittedChallenge = proof.getChallengeZero().add(proof.getChallengeOne()); 20 | ECPoint balanceClaim = proof.getCommitmentBalance().multiply(transmittedChallenge); 21 | ECPoint a1 = h.multiply(proof.getResponseV()).add(b.multiply(proof.getResponseS())).subtract(balanceClaim); 22 | ECPoint xHatClaim = proof.getCommitmentXHat().multiply(transmittedChallenge); 23 | ECPoint a2 = data.getPublicKey().multiply(proof.getResponseS()).add(h.multiply(proof.getResponseT())).subtract(xHatClaim); 24 | ECPoint a3 = g.multiply(proof.getResponseXHat()).add(h.multiply(proof.getResponseT())).subtract(xHatClaim); 25 | ECPoint zeroClaim = proof.getCommitmentBalance().multiply(proof.getChallengeZero()); 26 | ECPoint oneClaim = proof.getCommitmentBalance().subtract(b).multiply(proof.getChallengeOne()); 27 | 28 | ECPoint aZero = h.multiply(proof.getResponseZero()).subtract(zeroClaim); 29 | ECPoint aOne = h.multiply(proof.getResponseOne()).subtract(oneClaim); 30 | 31 | BigInteger computedChallenge = ProofUtils.computeChallenge(g, h, data.getPublicKey(), b, proof.getCommitmentBalance(), proof.getCommitmentXHat(), a1, a2, a3, aZero, aOne); 32 | this.holds(transmittedChallenge, computedChallenge); 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/verification/AddressVerificationData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.verification; 5 | 6 | import edu.stanford.crypto.proof.assets.AddressProof; 7 | import org.bouncycastle.math.ec.ECPoint; 8 | 9 | import java.math.BigInteger; 10 | 11 | public class AddressVerificationData 12 | implements VerificationData { 13 | private final ECPoint publicKey; 14 | private final BigInteger balance; 15 | private final ECPoint g; 16 | private final ECPoint h; 17 | 18 | public AddressVerificationData(ECPoint publicKey, BigInteger balance, ECPoint g, ECPoint h) { 19 | this.publicKey = publicKey; 20 | this.balance = balance; 21 | this.g = g; 22 | this.h = h; 23 | } 24 | 25 | public ECPoint getPublicKey() { 26 | return this.publicKey; 27 | } 28 | 29 | public BigInteger getBalance() { 30 | return this.balance; 31 | } 32 | 33 | public ECPoint getG() { 34 | return this.g; 35 | } 36 | 37 | public ECPoint getH() { 38 | return this.h; 39 | } 40 | } 41 | 42 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/verification/AssetsVerifier.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.verification; 5 | 6 | import edu.stanford.crypto.BlockingExecutor; 7 | import edu.stanford.crypto.ECConstants; 8 | import edu.stanford.crypto.bitcoin.SQLBlockchain; 9 | import edu.stanford.crypto.proof.assets.AddressProof; 10 | import edu.stanford.crypto.proof.assets.AddressProofEntry; 11 | import edu.stanford.crypto.proof.assets.AssetProof; 12 | import edu.stanford.crypto.proof.binary.BinaryProof; 13 | import org.bouncycastle.math.ec.ECPoint; 14 | 15 | import java.math.BigInteger; 16 | import java.sql.SQLException; 17 | import java.util.Iterator; 18 | import java.util.concurrent.ArrayBlockingQueue; 19 | import java.util.concurrent.BlockingQueue; 20 | import java.util.concurrent.TimeUnit; 21 | import java.util.concurrent.atomic.AtomicReference; 22 | import java.util.stream.Stream; 23 | 24 | public class AssetsVerifier 25 | implements Verifier> { 26 | private final AddressProofVerifier addressVerifier = new AddressProofVerifier(); 27 | private final BlockingQueue proofsQueue = new ArrayBlockingQueue<>(Runtime.getRuntime().availableProcessors() * 3); 28 | private final AtomicReference totalEncryption = new AtomicReference<>(ECConstants.INFINITY); 29 | 30 | @Override 31 | public void verify(AssetProof proof, GeneratorData data) { 32 | Iterator addressProofs = proof.getAddressProofs(); 33 | BlockingExecutor pool = new BlockingExecutor(); 34 | int nThreads = Runtime.getRuntime().availableProcessors() - 1; 35 | Stream.generate(AssetsVerificationWorker::new).limit(nThreads).forEach(pool::submit); 36 | 37 | try (SQLBlockchain blockchain = new SQLBlockchain()) { 38 | AddressProofEntry addressProofEntry; 39 | while (addressProofs.hasNext()) { 40 | addressProofEntry = addressProofs.next(); 41 | if (this.proofsQueue.offer(addressProofEntry)) continue; 42 | this.verifyAddressProof(blockchain, addressProofEntry); 43 | } 44 | while ((addressProofEntry = this.proofsQueue.poll()) != null) { 45 | this.verifyAddressProof(blockchain, addressProofEntry); 46 | } 47 | pool.shutdownNow(); 48 | pool.awaitTermination(1, TimeUnit.MINUTES); 49 | System.out.println("Total Encryption " + this.totalEncryption.get().normalize()); 50 | 51 | 52 | } catch (SQLException e) { 53 | e.printStackTrace(); 54 | throw new AssertionError(e); 55 | } catch (InterruptedException e) { 56 | e.printStackTrace(); 57 | throw new IllegalArgumentException("Couldn't complete proof"); 58 | } 59 | } 60 | 61 | private void verifyAddressProof(SQLBlockchain blockchain, AddressProofEntry addressProofEntry) { 62 | ECPoint publicKey = addressProofEntry.getPublicKey(); 63 | BigInteger balance = blockchain.getBalance(publicKey); 64 | AddressVerificationData addressVerificationData = new AddressVerificationData(publicKey, balance, ECConstants.G, ECConstants.H); 65 | AddressProof addressProof = addressProofEntry.getAddressProof(); 66 | this.addressVerifier.verify(addressProof, addressVerificationData); 67 | this.totalEncryption.accumulateAndGet(addressProof.getCommitmentBalance(), ECPoint::add); 68 | } 69 | 70 | private class AssetsVerificationWorker 71 | implements Runnable { 72 | private AssetsVerificationWorker() { 73 | } 74 | 75 | @Override 76 | public void run() { 77 | try (SQLBlockchain blockchain = new SQLBlockchain()) { 78 | 79 | while (!Thread.interrupted()) { 80 | try { 81 | AddressProofEntry addressProofEntry = AssetsVerifier.this.proofsQueue.take(); 82 | AssetsVerifier.this.verifyAddressProof(blockchain, addressProofEntry); 83 | } catch (InterruptedException e) { 84 | // empty catch block 85 | break; 86 | } 87 | } 88 | 89 | } catch (SQLException e) { 90 | e.printStackTrace(); 91 | throw new AssertionError(e); 92 | } 93 | } 94 | } 95 | 96 | } 97 | 98 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/verification/BalanceVerificationData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.verification; 5 | 6 | import edu.stanford.crypto.proof.balance.BalanceProof; 7 | 8 | public class BalanceVerificationData 9 | implements VerificationData { 10 | private final int maxBits; 11 | 12 | public BalanceVerificationData(int maxBits) { 13 | this.maxBits = maxBits; 14 | } 15 | 16 | public int getMaxBits() { 17 | return this.maxBits; 18 | } 19 | } 20 | 21 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/verification/BalanceVerifier.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.verification; 5 | 6 | import edu.stanford.crypto.BlockingExecutor; 7 | import edu.stanford.crypto.ECConstants; 8 | import edu.stanford.crypto.proof.balance.BalanceProof; 9 | import edu.stanford.crypto.proof.binary.BinaryProof; 10 | import edu.stanford.crypto.proof.binary.BinaryRangeProof; 11 | import org.bouncycastle.math.ec.ECPoint; 12 | 13 | import java.math.BigInteger; 14 | import java.util.Iterator; 15 | import java.util.concurrent.TimeUnit; 16 | import java.util.concurrent.atomic.AtomicReference; 17 | 18 | public class BalanceVerifier 19 | implements Verifier { 20 | private final BinaryRangeProofVerifier verifier = new BinaryRangeProofVerifier(); 21 | 22 | @Override 23 | public void verify(BalanceProof proof, BalanceVerificationData data) { 24 | Iterator rangeProofs = proof.getRangeProofs(); 25 | RangeProofVerificationData verificationData = new RangeProofVerificationData(new GeneratorData<>(), BigInteger.ONE.shiftLeft(data.getMaxBits()).subtract(BigInteger.ONE)); 26 | AtomicReference totalEncryption = new AtomicReference<>(ECConstants.INFINITY); 27 | BlockingExecutor pool = new BlockingExecutor(); 28 | while (rangeProofs.hasNext()) { 29 | BinaryRangeProof rangeProof = rangeProofs.next(); 30 | Runnable thread = () -> { 31 | this.verifier.verify(rangeProof, verificationData); 32 | totalEncryption.accumulateAndGet(rangeProof.getStatement(), ECPoint::add); 33 | }; 34 | pool.submit(thread); 35 | } 36 | try { 37 | pool.shutdown(); 38 | pool.awaitTermination(2, TimeUnit.DAYS); 39 | System.out.println(totalEncryption.get()); 40 | } 41 | catch (InterruptedException e) { 42 | e.printStackTrace(); 43 | throw new AssertionError(e); 44 | } 45 | } 46 | } 47 | 48 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/verification/BinaryProofVerifier.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.verification; 5 | 6 | import edu.stanford.crypto.ECConstants; 7 | import edu.stanford.crypto.ProofUtils; 8 | import edu.stanford.crypto.proof.binary.BinaryProof; 9 | import org.bouncycastle.math.ec.ECPoint; 10 | 11 | import java.math.BigInteger; 12 | 13 | public class BinaryProofVerifier 14 | implements Verifier> { 15 | @Override 16 | public void verify(BinaryProof proof, GeneratorData data) { 17 | ECPoint zeroClaim = proof.getStatement().multiply(proof.getChallengeZero()); 18 | ECPoint a0 = data.getH().multiply(proof.getResponseZero()).subtract(zeroClaim); 19 | ECPoint oneClaim = proof.getStatement().subtract(data.getG()).multiply(proof.getChallengeOne()); 20 | ECPoint a1 = data.getH().multiply(proof.getResponseOne()).subtract(oneClaim); 21 | BigInteger computedChallenge = ProofUtils.computeChallenge(data.getG(), data.getH(), proof.getStatement(), a0, a1); 22 | BigInteger transmittedChallenge = proof.getChallengeZero().add(proof.getChallengeOne()).mod(ECConstants.CHALLENGE_Q); 23 | this.holds(transmittedChallenge, computedChallenge); 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/verification/BinaryRangeProofVerifier.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.verification; 5 | 6 | import edu.stanford.crypto.proof.binary.BinaryProof; 7 | import edu.stanford.crypto.proof.binary.BinaryRangeProof; 8 | 9 | import java.util.List; 10 | 11 | public class BinaryRangeProofVerifier 12 | implements Verifier { 13 | private final BinaryProofVerifier binaryProofVerifier = new BinaryProofVerifier(); 14 | 15 | @Override 16 | public void verify(BinaryRangeProof proof, RangeProofVerificationData data) { 17 | if (data.getMaxRange().compareTo(proof.getRange()) > 0) { 18 | throw new AssertionError("Range is to small " + data.getMaxRange() + " should be less than " + proof.getRange()); 19 | } 20 | GeneratorData generatorData = data.getGeneratorData(); 21 | proof.getBitProofs().forEach(bp -> binaryProofVerifier.verify(bp, generatorData)); 22 | } 23 | } 24 | 25 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/verification/GeneratorData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.verification; 5 | 6 | import edu.stanford.crypto.ECConstants; 7 | import edu.stanford.crypto.proof.Proof; 8 | import org.bouncycastle.math.ec.ECPoint; 9 | 10 | public class GeneratorData

11 | implements VerificationData

{ 12 | private final ECPoint g; 13 | private final ECPoint h; 14 | 15 | public GeneratorData() { 16 | this(ECConstants.G, ECConstants.H); 17 | } 18 | 19 | private GeneratorData(ECPoint g, ECPoint h) { 20 | this.g = g; 21 | this.h = h; 22 | } 23 | 24 | public ECPoint getG() { 25 | return this.g; 26 | } 27 | 28 | public ECPoint getH() { 29 | return this.h; 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/verification/ParticipationData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.verification; 5 | 6 | import edu.stanford.crypto.proof.balance.BalanceProof; 7 | import edu.stanford.crypto.proof.balance.CustomerSecrets; 8 | 9 | import java.math.BigInteger; 10 | 11 | public class ParticipationData 12 | implements VerificationData { 13 | private final String customerId; 14 | private final CustomerSecrets secrets; 15 | private final BigInteger balance; 16 | 17 | public ParticipationData(String customerId, CustomerSecrets secrets, BigInteger balance) { 18 | this.customerId = customerId; 19 | this.secrets = secrets; 20 | this.balance = balance; 21 | } 22 | 23 | public String getCustomerId() { 24 | return this.customerId; 25 | } 26 | 27 | public CustomerSecrets getSecrets() { 28 | return this.secrets; 29 | } 30 | 31 | public BigInteger getBalance() { 32 | return this.balance; 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/verification/ParticipationVerifier.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.verification; 5 | 6 | import edu.stanford.crypto.ECConstants; 7 | import edu.stanford.crypto.ProofUtils; 8 | import edu.stanford.crypto.proof.balance.BalanceProof; 9 | import edu.stanford.crypto.proof.binary.BinaryRangeProof; 10 | import org.bouncycastle.math.ec.ECPoint; 11 | 12 | import java.math.BigInteger; 13 | 14 | public class ParticipationVerifier 15 | implements Verifier { 16 | @Override 17 | public void verify(BalanceProof proof, ParticipationData data) { 18 | BigInteger hashedId = ProofUtils.hash(data.getCustomerId(), data.getSecrets().getHashSalt()); 19 | BinaryRangeProof customerProof = proof.getCustomerProof(hashedId); 20 | ECPoint assumedStatement = ECConstants.H.multiply(data.getSecrets().getCombinedRandomness()).add(ECConstants.G.multiply(data.getBalance())); 21 | this.holds(assumedStatement, customerProof.getStatement()); 22 | } 23 | } 24 | 25 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/verification/RangeProofVerificationData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.verification; 5 | 6 | import edu.stanford.crypto.proof.binary.BinaryProof; 7 | import edu.stanford.crypto.proof.binary.BinaryRangeProof; 8 | 9 | import java.math.BigInteger; 10 | 11 | public class RangeProofVerificationData implements VerificationData { 12 | private final GeneratorData generatorData; 13 | private final BigInteger maxRange; 14 | 15 | public RangeProofVerificationData(GeneratorData generatorData, BigInteger maxRange) { 16 | this.generatorData = generatorData; 17 | this.maxRange = maxRange; 18 | } 19 | 20 | public GeneratorData getGeneratorData() { 21 | return this.generatorData; 22 | } 23 | 24 | public BigInteger getMaxRange() { 25 | return this.maxRange; 26 | } 27 | } 28 | 29 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/verification/VerificationData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.verification; 5 | 6 | import edu.stanford.crypto.proof.Proof; 7 | 8 | interface VerificationData

{ 9 | } 10 | 11 | -------------------------------------------------------------------------------- /src/main/java/edu/stanford/crypto/verification/Verifier.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Decompiled with CFR 0_110. 3 | */ 4 | package edu.stanford.crypto.verification; 5 | 6 | import edu.stanford.crypto.ECConstants; 7 | import edu.stanford.crypto.proof.Proof; 8 | import org.bouncycastle.math.ec.ECPoint; 9 | 10 | import java.math.BigInteger; 11 | 12 | interface Verifier

> { 13 | void verify(P var1, T var2); 14 | 15 | default void holds(ECPoint a, ECPoint b) { 16 | if (!a.equals(b)) { 17 | throw new AssertionError((Object)(a.normalize() + " should be equal to " + b.normalize())); 18 | } 19 | } 20 | 21 | default void holds(BigInteger a, BigInteger b) { 22 | if (!a.mod(ECConstants.Q).equals(b.mod(ECConstants.Q))) { 23 | throw new AssertionError((Object)(a + " should be equal to " + b)); 24 | } 25 | } 26 | } 27 | 28 | -------------------------------------------------------------------------------- /src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootLogger = DEBUG, CONSOLE 2 | 3 | 4 | log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender 5 | log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout 6 | log4j.appender.CONSOLE.layout.conversionPattern=%r [%t] %p %c %x - %m%n -------------------------------------------------------------------------------- /src/test/java/edu/stanford/crypto/PlayGround.java: -------------------------------------------------------------------------------- 1 | package edu.stanford.crypto; 2 | 3 | import org.junit.Test; 4 | 5 | import java.io.IOException; 6 | import java.security.NoSuchAlgorithmException; 7 | 8 | /** 9 | * Unit test for simple App. 10 | */ 11 | public class PlayGround { 12 | 13 | @Test 14 | public void playGround2() throws IOException, NoSuchAlgorithmException { 15 | 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/test/java/edu/stanford/crypto/proof/assets/AddressProofTest.java: -------------------------------------------------------------------------------- 1 | package edu.stanford.crypto.proof.assets; 2 | 3 | import edu.stanford.crypto.ECConstants; 4 | import edu.stanford.crypto.verification.AddressProofVerifier; 5 | import edu.stanford.crypto.verification.AddressVerificationData; 6 | import org.bouncycastle.math.ec.ECPoint; 7 | import org.junit.Test; 8 | 9 | import java.math.BigInteger; 10 | import java.security.SecureRandom; 11 | import java.util.Random; 12 | 13 | /** 14 | * Created by buenz on 06.01.16. 15 | */ 16 | public class AddressProofTest { 17 | @Test 18 | public void testAddressProofWithKey() { 19 | AddressProofSystem system = new AddressProofSystem(); 20 | Random rng = new SecureRandom(); 21 | 22 | BigInteger privateKey = new BigInteger(256, rng); 23 | ECPoint pubKey = ECConstants.G.multiply(privateKey); 24 | BigInteger balance = BigInteger.TEN; 25 | BigInteger balanceRandomness = new BigInteger(256, rng); 26 | BigInteger knownKeyRandomness = new BigInteger(256, rng); 27 | 28 | AddressProofData data = new AddressProofData(privateKey, pubKey, balance, balanceRandomness, knownKeyRandomness, ECConstants.G, ECConstants.H); 29 | AddressProof proof = system.createProof(data); 30 | AddressProofVerifier verifier = new AddressProofVerifier(); 31 | AddressVerificationData verificaitonData = new AddressVerificationData(pubKey, balance, ECConstants.G, ECConstants.H); 32 | verifier.verify(proof, verificaitonData); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/test/java/edu/stanford/crypto/proof/assets/RangeProofTest.java: -------------------------------------------------------------------------------- 1 | package edu.stanford.crypto.proof.assets; 2 | 3 | import edu.stanford.crypto.proof.RangeProofData; 4 | import edu.stanford.crypto.proof.binary.BinaryRangeProof; 5 | import edu.stanford.crypto.proof.rangeproof.BinaryRangeProofSystem; 6 | import edu.stanford.crypto.verification.BinaryRangeProofVerifier; 7 | import edu.stanford.crypto.verification.GeneratorData; 8 | import edu.stanford.crypto.verification.RangeProofVerificationData; 9 | import org.junit.Rule; 10 | import org.junit.Test; 11 | import org.junit.rules.ExpectedException; 12 | 13 | import java.math.BigInteger; 14 | import java.security.SecureRandom; 15 | import java.util.List; 16 | import java.util.stream.Collectors; 17 | import java.util.stream.Stream; 18 | 19 | /** 20 | * Created by buenz on 07.01.16. 21 | */ 22 | public class RangeProofTest { 23 | @Rule 24 | public final ExpectedException exception = ExpectedException.none(); 25 | 26 | @Test 27 | public void testRangeProof() { 28 | BinaryRangeProofSystem rangeProofSystem = new BinaryRangeProofSystem(); 29 | BigInteger secretData = BigInteger.TEN; 30 | SecureRandom rng = new SecureRandom(); 31 | List hidingFactors = Stream.generate(() -> new BigInteger(256, rng)).limit(4).collect(Collectors.toList()); 32 | RangeProofData data = new RangeProofData(secretData, hidingFactors); 33 | BinaryRangeProof proof = rangeProofSystem.createProof(data); 34 | BinaryRangeProofVerifier verifier=new BinaryRangeProofVerifier(); 35 | 36 | RangeProofVerificationData rangeProofVerificationData=new RangeProofVerificationData(new GeneratorData<>(),BigInteger.valueOf(15)); 37 | 38 | verifier.verify(proof,rangeProofVerificationData); 39 | 40 | } 41 | @Test 42 | public void testFailedRangeProof(){ 43 | exception.expect(AssertionError.class); 44 | BinaryRangeProofSystem rangeProofSystem = new BinaryRangeProofSystem(); 45 | BigInteger secretData = BigInteger.valueOf(2); 46 | SecureRandom rng = new SecureRandom(); 47 | List hidingFactors = Stream.generate(() -> new BigInteger(256, rng)).limit(3).collect(Collectors.toList()); 48 | RangeProofData data = new RangeProofData(secretData, hidingFactors); 49 | BinaryRangeProof proof = rangeProofSystem.createProof(data); 50 | BinaryRangeProofVerifier verifier=new BinaryRangeProofVerifier(); 51 | 52 | RangeProofVerificationData rangeProofVerificationData=new RangeProofVerificationData(new GeneratorData<>(),BigInteger.valueOf(15)); 53 | 54 | verifier.verify(proof,rangeProofVerificationData); 55 | } 56 | } 57 | --------------------------------------------------------------------------------