diff --git a/README.md b/README.md index 262141bb2a..61809e7300 100644 --- a/README.md +++ b/README.md @@ -13,13 +13,13 @@ Apollo isn't designed for coins, rather as essentially a distributed multitenant ## Some Features * Multitenant isolation enclaves using GraalVM Isolates -* Compact, self contained Crypto and Utility module - Self certifying, self describing Digests, Signatures and Identifiers as well as a generous sampling of solid Bloomfilters n cousins. +* Self contained cryptography module - Self describing Digests, Signatures and Identifiers, solid Bloomfilters. * Decentralized Identifier based foundation and key managment infrastructure, based on the [Key Event Receipt Infrastructure](https://github.com/decentralized-identity/keri) (KERI) * Secure and trusted attestation, identity boostrapping and secrets provisioning * MTLS network communication - KERI for MTLS certificate authentication. Local communication simulation for simplified multinode simulation for single process (IDE) testing * Multi instance GRPC service routing - Context keyed services and routing framework * Byzantine intrusion tolerant secure membership and communications overlay providing virtually synchronous, stable membership views. -* Efficient and easy to reuse utility patterns for Fireflies ring style gossiping on membership contexts +* Efficient and easy to reuse communication patterns for Fireflies ring style gossiping on membership contexts * Reliable Broadcast - garbage collected, context routed reliable broadcast * Efficient atomic broadcast in asynchronous networks with byzantine nodes * Dynamic, committee based, transaction causal ordering service producing linear logs - Replicated State Machines @@ -85,7 +85,7 @@ Apollo is reasonably modularized mostly for the purpose of subsystem isolation a * [Stereotomy Services](stereotomy-services) - GRPC services and protobuff interfaces for KERI services * [Thoth](thoth/README.md) - Decentralized Stereotomy. Distributed hash table storage, protocols and API for managing KERI decentralized identity * [Tron](tron/README.md) - Compact, sophisticated Finite State Machine model using Java Enums. -* [Utils](utils/README.md) - Base cryptography primitives and model. Bloom filters (of several varieties). Some general utility stuff. +* [Cryptography](cryptography/README.md) - Base cryptography primitives. Bloom filters (of several varieties). Some general utility stuff. ## Protobuf and GRPC diff --git a/choam/src/main/java/com/salesforce/apollo/choam/CHOAM.java b/choam/src/main/java/com/salesforce/apollo/choam/CHOAM.java index 9d6f77f5aa..3bbd25ecdb 100644 --- a/choam/src/main/java/com/salesforce/apollo/choam/CHOAM.java +++ b/choam/src/main/java/com/salesforce/apollo/choam/CHOAM.java @@ -32,9 +32,9 @@ import com.salesforce.apollo.membership.messaging.rbc.ReliableBroadcaster; import com.salesforce.apollo.membership.messaging.rbc.ReliableBroadcaster.MessageAdapter; import com.salesforce.apollo.membership.messaging.rbc.ReliableBroadcaster.Msg; -import com.salesforce.apollo.utils.RoundScheduler; +import com.salesforce.apollo.membership.RoundScheduler; import com.salesforce.apollo.utils.Utils; -import com.salesforce.apollo.utils.bloomFilters.BloomFilter; +import com.salesforce.apollo.bloomFilters.BloomFilter; import io.grpc.StatusRuntimeException; import org.h2.mvstore.MVMap; import org.joou.ULong; diff --git a/utils/src/main/java/com/salesforce/apollo/utils/BatchingQueue.java b/choam/src/main/java/com/salesforce/apollo/choam/support/BatchingQueue.java similarity index 99% rename from utils/src/main/java/com/salesforce/apollo/utils/BatchingQueue.java rename to choam/src/main/java/com/salesforce/apollo/choam/support/BatchingQueue.java index c36f86c491..d24f0b488e 100644 --- a/utils/src/main/java/com/salesforce/apollo/utils/BatchingQueue.java +++ b/choam/src/main/java/com/salesforce/apollo/choam/support/BatchingQueue.java @@ -1,4 +1,4 @@ -package com.salesforce.apollo.utils; +package com.salesforce.apollo.choam.support; import java.time.Duration; import java.util.ArrayList; diff --git a/choam/src/main/java/com/salesforce/apollo/choam/support/Bootstrapper.java b/choam/src/main/java/com/salesforce/apollo/choam/support/Bootstrapper.java index ae9f149fc9..cd5eb22fa4 100644 --- a/choam/src/main/java/com/salesforce/apollo/choam/support/Bootstrapper.java +++ b/choam/src/main/java/com/salesforce/apollo/choam/support/Bootstrapper.java @@ -20,8 +20,8 @@ import com.salesforce.apollo.ring.RingIterator; import com.salesforce.apollo.utils.Entropy; import com.salesforce.apollo.utils.Pair; -import com.salesforce.apollo.utils.bloomFilters.BloomFilter; -import com.salesforce.apollo.utils.bloomFilters.BloomFilter.ULongBloomFilter; +import com.salesforce.apollo.bloomFilters.BloomFilter; +import com.salesforce.apollo.bloomFilters.BloomFilter.ULongBloomFilter; import org.joou.ULong; import org.joou.Unsigned; import org.slf4j.Logger; @@ -279,7 +279,7 @@ private void computeGenesis(Map votes) { for (HashedCertifiedBlock cb : tally) { int count = tally.count(cb); if (count >= threshold) { - if (winner == null || count > winner.b) { + if (winner == null || count > winner.b()) { winner = new Pair<>(cb, count); } } @@ -291,7 +291,7 @@ private void computeGenesis(Map votes) { return; } - genesis = winner.a; + genesis = winner.a(); log.info("Winner: {} on: {}", genesis.hash, params.member().getId()); } diff --git a/choam/src/main/java/com/salesforce/apollo/choam/support/CheckpointAssembler.java b/choam/src/main/java/com/salesforce/apollo/choam/support/CheckpointAssembler.java index d1255332cf..fb5d2a9c1a 100644 --- a/choam/src/main/java/com/salesforce/apollo/choam/support/CheckpointAssembler.java +++ b/choam/src/main/java/com/salesforce/apollo/choam/support/CheckpointAssembler.java @@ -19,7 +19,7 @@ import com.salesforce.apollo.membership.SigningMember; import com.salesforce.apollo.ring.RingIterator; import com.salesforce.apollo.utils.Entropy; -import com.salesforce.apollo.utils.bloomFilters.BloomFilter; +import com.salesforce.apollo.bloomFilters.BloomFilter; import org.h2.mvstore.MVMap; import org.joou.ULong; import org.slf4j.Logger; diff --git a/choam/src/main/java/com/salesforce/apollo/choam/support/CheckpointState.java b/choam/src/main/java/com/salesforce/apollo/choam/support/CheckpointState.java index 87a588bb20..824fec4a3f 100644 --- a/choam/src/main/java/com/salesforce/apollo/choam/support/CheckpointState.java +++ b/choam/src/main/java/com/salesforce/apollo/choam/support/CheckpointState.java @@ -24,7 +24,7 @@ import com.salesfoce.apollo.choam.proto.Checkpoint; import com.salesfoce.apollo.choam.proto.Slice; import com.salesforce.apollo.utils.Utils; -import com.salesforce.apollo.utils.bloomFilters.BloomFilter; +import com.salesforce.apollo.bloomFilters.BloomFilter; /** * @author hal.hildebrand diff --git a/choam/src/main/java/com/salesforce/apollo/choam/support/Store.java b/choam/src/main/java/com/salesforce/apollo/choam/support/Store.java index c3b27d0108..1e4f6d9774 100644 --- a/choam/src/main/java/com/salesforce/apollo/choam/support/Store.java +++ b/choam/src/main/java/com/salesforce/apollo/choam/support/Store.java @@ -38,7 +38,7 @@ import com.salesfoce.apollo.choam.proto.Checkpoint; import com.salesforce.apollo.crypto.Digest; import com.salesforce.apollo.crypto.DigestAlgorithm; -import com.salesforce.apollo.utils.bloomFilters.BloomFilter; +import com.salesforce.apollo.bloomFilters.BloomFilter; /** * Kind of a DAO for "nosql" block storage with MVStore from H2 diff --git a/choam/src/main/java/com/salesforce/apollo/choam/support/TxDataSource.java b/choam/src/main/java/com/salesforce/apollo/choam/support/TxDataSource.java index 9ac892467a..cd91da18a0 100644 --- a/choam/src/main/java/com/salesforce/apollo/choam/support/TxDataSource.java +++ b/choam/src/main/java/com/salesforce/apollo/choam/support/TxDataSource.java @@ -23,7 +23,6 @@ import com.salesfoce.apollo.choam.proto.Validate; import com.salesforce.apollo.ethereal.DataSource; import com.salesforce.apollo.membership.Member; -import com.salesforce.apollo.utils.BatchingQueue; /** * diff --git a/utils/src/test/java/com/salesforce/apollo/utils/BatchingQueueTest.java b/choam/src/test/java/com/salesforce/apollo/choam/support/BatchingQueueTest.java similarity index 92% rename from utils/src/test/java/com/salesforce/apollo/utils/BatchingQueueTest.java rename to choam/src/test/java/com/salesforce/apollo/choam/support/BatchingQueueTest.java index d6b11866e1..d5bf76060b 100644 --- a/utils/src/test/java/com/salesforce/apollo/utils/BatchingQueueTest.java +++ b/choam/src/test/java/com/salesforce/apollo/choam/support/BatchingQueueTest.java @@ -1,4 +1,4 @@ -package com.salesforce.apollo.utils; +package com.salesforce.apollo.choam.support; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -8,6 +8,8 @@ import java.time.Duration; +import com.salesforce.apollo.choam.support.BatchingQueue; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; /** diff --git a/choam/src/test/java/com/salesforce/apollo/choam/support/BootstrapperTest.java b/choam/src/test/java/com/salesforce/apollo/choam/support/BootstrapperTest.java index 1bc97fc408..9628507639 100644 --- a/choam/src/test/java/com/salesforce/apollo/choam/support/BootstrapperTest.java +++ b/choam/src/test/java/com/salesforce/apollo/choam/support/BootstrapperTest.java @@ -25,7 +25,7 @@ import com.salesforce.apollo.stereotomy.StereotomyImpl; import com.salesforce.apollo.stereotomy.mem.MemKERL; import com.salesforce.apollo.stereotomy.mem.MemKeyStore; -import com.salesforce.apollo.utils.bloomFilters.BloomFilter; +import com.salesforce.apollo.bloomFilters.BloomFilter; import org.h2.mvstore.MVStore; import org.joou.ULong; import org.junit.jupiter.api.Test; diff --git a/choam/src/test/java/com/salesforce/apollo/choam/support/CheckpointAssemblerTest.java b/choam/src/test/java/com/salesforce/apollo/choam/support/CheckpointAssemblerTest.java index e058a10ab2..41faa1f632 100644 --- a/choam/src/test/java/com/salesforce/apollo/choam/support/CheckpointAssemblerTest.java +++ b/choam/src/test/java/com/salesforce/apollo/choam/support/CheckpointAssemblerTest.java @@ -25,7 +25,7 @@ import com.salesforce.apollo.stereotomy.mem.MemKERL; import com.salesforce.apollo.stereotomy.mem.MemKeyStore; import com.salesforce.apollo.utils.Utils; -import com.salesforce.apollo.utils.bloomFilters.BloomFilter; +import com.salesforce.apollo.bloomFilters.BloomFilter; import org.h2.mvstore.MVStore; import org.joou.ULong; import org.junit.jupiter.api.AfterEach; diff --git a/cryptography/README.md b/cryptography/README.md new file mode 100644 index 0000000000..0c42113c8b --- /dev/null +++ b/cryptography/README.md @@ -0,0 +1,2 @@ +# Apollo Cryptography +Digests, signatures, keys, Bloom Filters, etc. diff --git a/utils/pom.xml b/cryptography/pom.xml similarity index 84% rename from utils/pom.xml rename to cryptography/pom.xml index d72082193c..5529f7dcad 100644 --- a/utils/pom.xml +++ b/cryptography/pom.xml @@ -1,13 +1,17 @@ - + + 4.0.0 com.salesforce.apollo apollo.app 0.0.1-SNAPSHOT - utils - Utils - General utilities, Bloomfilters and cryptographic abstractions + + cryptography + Cryptography + Digests, Signatures, Bloomfilters and cryptographic abstractions @@ -73,4 +77,4 @@ test - \ No newline at end of file + diff --git a/utils/src/main/java/com/salesforce/apollo/utils/bloomFilters/BloomFilter.java b/cryptography/src/main/java/com/salesforce/apollo/bloomFilters/BloomFilter.java similarity index 99% rename from utils/src/main/java/com/salesforce/apollo/utils/bloomFilters/BloomFilter.java rename to cryptography/src/main/java/com/salesforce/apollo/bloomFilters/BloomFilter.java index 2d30860854..ab6091e9db 100644 --- a/utils/src/main/java/com/salesforce/apollo/utils/bloomFilters/BloomFilter.java +++ b/cryptography/src/main/java/com/salesforce/apollo/bloomFilters/BloomFilter.java @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ -package com.salesforce.apollo.utils.bloomFilters; +package com.salesforce.apollo.bloomFilters; import java.util.BitSet; import java.util.function.Consumer; diff --git a/utils/src/main/java/com/salesforce/apollo/utils/bloomFilters/BloomWindow.java b/cryptography/src/main/java/com/salesforce/apollo/bloomFilters/BloomWindow.java similarity index 98% rename from utils/src/main/java/com/salesforce/apollo/utils/bloomFilters/BloomWindow.java rename to cryptography/src/main/java/com/salesforce/apollo/bloomFilters/BloomWindow.java index cc1fd4594e..8684249a57 100644 --- a/utils/src/main/java/com/salesforce/apollo/utils/bloomFilters/BloomWindow.java +++ b/cryptography/src/main/java/com/salesforce/apollo/bloomFilters/BloomWindow.java @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ -package com.salesforce.apollo.utils.bloomFilters; +package com.salesforce.apollo.bloomFilters; import java.util.concurrent.BlockingDeque; import java.util.concurrent.LinkedBlockingDeque; diff --git a/utils/src/main/java/com/salesforce/apollo/utils/bloomFilters/Hash.java b/cryptography/src/main/java/com/salesforce/apollo/bloomFilters/Hash.java similarity index 97% rename from utils/src/main/java/com/salesforce/apollo/utils/bloomFilters/Hash.java rename to cryptography/src/main/java/com/salesforce/apollo/bloomFilters/Hash.java index d81205e2e2..785ad27a49 100644 --- a/utils/src/main/java/com/salesforce/apollo/utils/bloomFilters/Hash.java +++ b/cryptography/src/main/java/com/salesforce/apollo/bloomFilters/Hash.java @@ -4,9 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ -package com.salesforce.apollo.utils.bloomFilters; - -import static com.salesforce.apollo.utils.bloomFilters.Primes.PRIMES; +package com.salesforce.apollo.bloomFilters; import java.nio.ByteBuffer; import java.util.stream.IntStream; @@ -118,8 +116,8 @@ public int[] hashes(int k, M key, int m, long seed) { hashes[i++] = hash; // HITS++; } else { - h2 += PRIMES[prime]; - prime = ++prime % PRIMES.length; + h2 += Primes.PRIMES[prime]; + prime = ++prime % Primes.PRIMES.length; // MISSES++; } combinedHash += h2; @@ -178,9 +176,9 @@ void process(int i) { int reversed = Integer.reverse(i); ByteBuffer bb = ByteBuffer.wrap(new byte[2 * 8]); bb.putInt(i); - bb.putInt(i + PRIMES[(i & Integer.MAX_VALUE) % PRIMES.length]); + bb.putInt(i + Primes.PRIMES[(i & Integer.MAX_VALUE) % Primes.PRIMES.length]); bb.putInt(reversed); - bb.putInt(reversed + PRIMES[((i + 1) & Integer.MAX_VALUE) % PRIMES.length]); + bb.putInt(reversed + Primes.PRIMES[((i + 1) & Integer.MAX_VALUE) % Primes.PRIMES.length]); bb.flip(); process(bb); } diff --git a/utils/src/main/java/com/salesforce/apollo/utils/bloomFilters/Primes.java b/cryptography/src/main/java/com/salesforce/apollo/bloomFilters/Primes.java similarity index 99% rename from utils/src/main/java/com/salesforce/apollo/utils/bloomFilters/Primes.java rename to cryptography/src/main/java/com/salesforce/apollo/bloomFilters/Primes.java index 3f29bc6c17..e745aebcd1 100644 --- a/utils/src/main/java/com/salesforce/apollo/utils/bloomFilters/Primes.java +++ b/cryptography/src/main/java/com/salesforce/apollo/bloomFilters/Primes.java @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ -package com.salesforce.apollo.utils.bloomFilters; +package com.salesforce.apollo.bloomFilters; /** * @author hal.hildebrand diff --git a/utils/src/main/java/com/salesforce/apollo/crypto/Digest.java b/cryptography/src/main/java/com/salesforce/apollo/crypto/Digest.java similarity index 99% rename from utils/src/main/java/com/salesforce/apollo/crypto/Digest.java rename to cryptography/src/main/java/com/salesforce/apollo/crypto/Digest.java index c094493d78..c63304b708 100644 --- a/utils/src/main/java/com/salesforce/apollo/crypto/Digest.java +++ b/cryptography/src/main/java/com/salesforce/apollo/crypto/Digest.java @@ -13,7 +13,7 @@ import com.salesfoce.apollo.utils.proto.Digeste.Builder; import com.salesforce.apollo.utils.BUZ; import com.salesforce.apollo.utils.Hex; -import com.salesforce.apollo.utils.bloomFilters.Hash; +import com.salesforce.apollo.bloomFilters.Hash; /** * A computed digest diff --git a/utils/src/main/java/com/salesforce/apollo/crypto/DigestAlgorithm.java b/cryptography/src/main/java/com/salesforce/apollo/crypto/DigestAlgorithm.java similarity index 100% rename from utils/src/main/java/com/salesforce/apollo/crypto/DigestAlgorithm.java rename to cryptography/src/main/java/com/salesforce/apollo/crypto/DigestAlgorithm.java diff --git a/utils/src/main/java/com/salesforce/apollo/crypto/EdDSAOperations.java b/cryptography/src/main/java/com/salesforce/apollo/crypto/EdDSAOperations.java similarity index 100% rename from utils/src/main/java/com/salesforce/apollo/crypto/EdDSAOperations.java rename to cryptography/src/main/java/com/salesforce/apollo/crypto/EdDSAOperations.java diff --git a/utils/src/main/java/com/salesforce/apollo/crypto/HexBloom.java b/cryptography/src/main/java/com/salesforce/apollo/crypto/HexBloom.java similarity index 99% rename from utils/src/main/java/com/salesforce/apollo/crypto/HexBloom.java rename to cryptography/src/main/java/com/salesforce/apollo/crypto/HexBloom.java index 1df361bf9d..640b730542 100644 --- a/utils/src/main/java/com/salesforce/apollo/crypto/HexBloom.java +++ b/cryptography/src/main/java/com/salesforce/apollo/crypto/HexBloom.java @@ -16,8 +16,8 @@ import java.util.stream.Stream; import com.salesfoce.apollo.utils.proto.HexBloome; -import com.salesforce.apollo.utils.bloomFilters.BloomFilter; -import com.salesforce.apollo.utils.bloomFilters.Primes; +import com.salesforce.apollo.bloomFilters.BloomFilter; +import com.salesforce.apollo.bloomFilters.Primes; /** * Based on the paper HEX-BLOOM: diff --git a/utils/src/main/java/com/salesforce/apollo/crypto/JohnHancock.java b/cryptography/src/main/java/com/salesforce/apollo/crypto/JohnHancock.java similarity index 100% rename from utils/src/main/java/com/salesforce/apollo/crypto/JohnHancock.java rename to cryptography/src/main/java/com/salesforce/apollo/crypto/JohnHancock.java diff --git a/utils/src/main/java/com/salesforce/apollo/crypto/QualifiedBase64.java b/cryptography/src/main/java/com/salesforce/apollo/crypto/QualifiedBase64.java similarity index 100% rename from utils/src/main/java/com/salesforce/apollo/crypto/QualifiedBase64.java rename to cryptography/src/main/java/com/salesforce/apollo/crypto/QualifiedBase64.java diff --git a/utils/src/main/java/com/salesforce/apollo/crypto/SignatureAlgorithm.java b/cryptography/src/main/java/com/salesforce/apollo/crypto/SignatureAlgorithm.java similarity index 100% rename from utils/src/main/java/com/salesforce/apollo/crypto/SignatureAlgorithm.java rename to cryptography/src/main/java/com/salesforce/apollo/crypto/SignatureAlgorithm.java diff --git a/utils/src/main/java/com/salesforce/apollo/crypto/Signer.java b/cryptography/src/main/java/com/salesforce/apollo/crypto/Signer.java similarity index 100% rename from utils/src/main/java/com/salesforce/apollo/crypto/Signer.java rename to cryptography/src/main/java/com/salesforce/apollo/crypto/Signer.java diff --git a/utils/src/main/java/com/salesforce/apollo/crypto/SigningThreshold.java b/cryptography/src/main/java/com/salesforce/apollo/crypto/SigningThreshold.java similarity index 100% rename from utils/src/main/java/com/salesforce/apollo/crypto/SigningThreshold.java rename to cryptography/src/main/java/com/salesforce/apollo/crypto/SigningThreshold.java diff --git a/utils/src/main/java/com/salesforce/apollo/crypto/Verifier.java b/cryptography/src/main/java/com/salesforce/apollo/crypto/Verifier.java similarity index 100% rename from utils/src/main/java/com/salesforce/apollo/crypto/Verifier.java rename to cryptography/src/main/java/com/salesforce/apollo/crypto/Verifier.java diff --git a/utils/src/main/java/com/salesforce/apollo/crypto/cert/BcX500NameDnImpl.java b/cryptography/src/main/java/com/salesforce/apollo/crypto/cert/BcX500NameDnImpl.java similarity index 100% rename from utils/src/main/java/com/salesforce/apollo/crypto/cert/BcX500NameDnImpl.java rename to cryptography/src/main/java/com/salesforce/apollo/crypto/cert/BcX500NameDnImpl.java diff --git a/utils/src/main/java/com/salesforce/apollo/crypto/cert/CertExtension.java b/cryptography/src/main/java/com/salesforce/apollo/crypto/cert/CertExtension.java similarity index 100% rename from utils/src/main/java/com/salesforce/apollo/crypto/cert/CertExtension.java rename to cryptography/src/main/java/com/salesforce/apollo/crypto/cert/CertExtension.java diff --git a/utils/src/main/java/com/salesforce/apollo/crypto/cert/CertificateWithPrivateKey.java b/cryptography/src/main/java/com/salesforce/apollo/crypto/cert/CertificateWithPrivateKey.java similarity index 100% rename from utils/src/main/java/com/salesforce/apollo/crypto/cert/CertificateWithPrivateKey.java rename to cryptography/src/main/java/com/salesforce/apollo/crypto/cert/CertificateWithPrivateKey.java diff --git a/utils/src/main/java/com/salesforce/apollo/crypto/cert/Certificates.java b/cryptography/src/main/java/com/salesforce/apollo/crypto/cert/Certificates.java similarity index 100% rename from utils/src/main/java/com/salesforce/apollo/crypto/cert/Certificates.java rename to cryptography/src/main/java/com/salesforce/apollo/crypto/cert/Certificates.java diff --git a/utils/src/main/java/com/salesforce/apollo/crypto/cert/CrlDistPointExtension.java b/cryptography/src/main/java/com/salesforce/apollo/crypto/cert/CrlDistPointExtension.java similarity index 100% rename from utils/src/main/java/com/salesforce/apollo/crypto/cert/CrlDistPointExtension.java rename to cryptography/src/main/java/com/salesforce/apollo/crypto/cert/CrlDistPointExtension.java diff --git a/utils/src/main/java/com/salesforce/apollo/crypto/cert/ExtKeyUsageExtension.java b/cryptography/src/main/java/com/salesforce/apollo/crypto/cert/ExtKeyUsageExtension.java similarity index 100% rename from utils/src/main/java/com/salesforce/apollo/crypto/cert/ExtKeyUsageExtension.java rename to cryptography/src/main/java/com/salesforce/apollo/crypto/cert/ExtKeyUsageExtension.java diff --git a/utils/src/main/java/com/salesforce/apollo/crypto/cert/KeyUsageExtension.java b/cryptography/src/main/java/com/salesforce/apollo/crypto/cert/KeyUsageExtension.java similarity index 100% rename from utils/src/main/java/com/salesforce/apollo/crypto/cert/KeyUsageExtension.java rename to cryptography/src/main/java/com/salesforce/apollo/crypto/cert/KeyUsageExtension.java diff --git a/utils/src/main/java/com/salesforce/apollo/crypto/cert/NameType.java b/cryptography/src/main/java/com/salesforce/apollo/crypto/cert/NameType.java similarity index 100% rename from utils/src/main/java/com/salesforce/apollo/crypto/cert/NameType.java rename to cryptography/src/main/java/com/salesforce/apollo/crypto/cert/NameType.java diff --git a/utils/src/main/java/com/salesforce/apollo/crypto/ssl/CertificateValidator.java b/cryptography/src/main/java/com/salesforce/apollo/crypto/ssl/CertificateValidator.java similarity index 100% rename from utils/src/main/java/com/salesforce/apollo/crypto/ssl/CertificateValidator.java rename to cryptography/src/main/java/com/salesforce/apollo/crypto/ssl/CertificateValidator.java diff --git a/utils/src/main/java/com/salesforce/apollo/crypto/ssl/Keys.java b/cryptography/src/main/java/com/salesforce/apollo/crypto/ssl/Keys.java similarity index 100% rename from utils/src/main/java/com/salesforce/apollo/crypto/ssl/Keys.java rename to cryptography/src/main/java/com/salesforce/apollo/crypto/ssl/Keys.java diff --git a/utils/src/main/java/com/salesforce/apollo/crypto/ssl/NodeKeyManagerFactory.java b/cryptography/src/main/java/com/salesforce/apollo/crypto/ssl/NodeKeyManagerFactory.java similarity index 100% rename from utils/src/main/java/com/salesforce/apollo/crypto/ssl/NodeKeyManagerFactory.java rename to cryptography/src/main/java/com/salesforce/apollo/crypto/ssl/NodeKeyManagerFactory.java diff --git a/utils/src/main/java/com/salesforce/apollo/crypto/ssl/NodeKeyManagerFactorySpi.java b/cryptography/src/main/java/com/salesforce/apollo/crypto/ssl/NodeKeyManagerFactorySpi.java similarity index 100% rename from utils/src/main/java/com/salesforce/apollo/crypto/ssl/NodeKeyManagerFactorySpi.java rename to cryptography/src/main/java/com/salesforce/apollo/crypto/ssl/NodeKeyManagerFactorySpi.java diff --git a/utils/src/main/java/com/salesforce/apollo/crypto/ssl/NodeTrustManagerFactory.java b/cryptography/src/main/java/com/salesforce/apollo/crypto/ssl/NodeTrustManagerFactory.java similarity index 100% rename from utils/src/main/java/com/salesforce/apollo/crypto/ssl/NodeTrustManagerFactory.java rename to cryptography/src/main/java/com/salesforce/apollo/crypto/ssl/NodeTrustManagerFactory.java diff --git a/utils/src/main/java/com/salesforce/apollo/crypto/ssl/NodeTrustManagerFactorySpi.java b/cryptography/src/main/java/com/salesforce/apollo/crypto/ssl/NodeTrustManagerFactorySpi.java similarity index 100% rename from utils/src/main/java/com/salesforce/apollo/crypto/ssl/NodeTrustManagerFactorySpi.java rename to cryptography/src/main/java/com/salesforce/apollo/crypto/ssl/NodeTrustManagerFactorySpi.java diff --git a/utils/src/main/java/com/salesforce/apollo/crypto/ssl/TlsInterceptor.java b/cryptography/src/main/java/com/salesforce/apollo/crypto/ssl/TlsInterceptor.java similarity index 100% rename from utils/src/main/java/com/salesforce/apollo/crypto/ssl/TlsInterceptor.java rename to cryptography/src/main/java/com/salesforce/apollo/crypto/ssl/TlsInterceptor.java diff --git a/utils/src/main/java/com/salesforce/apollo/crypto/ssl/Trust.java b/cryptography/src/main/java/com/salesforce/apollo/crypto/ssl/Trust.java similarity index 100% rename from utils/src/main/java/com/salesforce/apollo/crypto/ssl/Trust.java rename to cryptography/src/main/java/com/salesforce/apollo/crypto/ssl/Trust.java diff --git a/utils/src/main/java/com/salesforce/apollo/utils/BUZ.java b/cryptography/src/main/java/com/salesforce/apollo/utils/BUZ.java similarity index 100% rename from utils/src/main/java/com/salesforce/apollo/utils/BUZ.java rename to cryptography/src/main/java/com/salesforce/apollo/utils/BUZ.java diff --git a/utils/src/main/java/com/salesforce/apollo/utils/BbBackedInputStream.java b/cryptography/src/main/java/com/salesforce/apollo/utils/BbBackedInputStream.java similarity index 100% rename from utils/src/main/java/com/salesforce/apollo/utils/BbBackedInputStream.java rename to cryptography/src/main/java/com/salesforce/apollo/utils/BbBackedInputStream.java diff --git a/utils/src/main/java/com/salesforce/apollo/utils/BbBackedOutputStream.java b/cryptography/src/main/java/com/salesforce/apollo/utils/BbBackedOutputStream.java similarity index 100% rename from utils/src/main/java/com/salesforce/apollo/utils/BbBackedOutputStream.java rename to cryptography/src/main/java/com/salesforce/apollo/utils/BbBackedOutputStream.java diff --git a/utils/src/main/java/com/salesforce/apollo/utils/Entropy.java b/cryptography/src/main/java/com/salesforce/apollo/utils/Entropy.java similarity index 100% rename from utils/src/main/java/com/salesforce/apollo/utils/Entropy.java rename to cryptography/src/main/java/com/salesforce/apollo/utils/Entropy.java diff --git a/utils/src/main/java/com/salesforce/apollo/utils/Hex.java b/cryptography/src/main/java/com/salesforce/apollo/utils/Hex.java similarity index 100% rename from utils/src/main/java/com/salesforce/apollo/utils/Hex.java rename to cryptography/src/main/java/com/salesforce/apollo/utils/Hex.java diff --git a/utils/src/main/java/com/salesforce/apollo/causal/StampedClockValue.java b/cryptography/src/main/java/com/salesforce/apollo/utils/Pair.java similarity index 51% rename from utils/src/main/java/com/salesforce/apollo/causal/StampedClockValue.java rename to cryptography/src/main/java/com/salesforce/apollo/utils/Pair.java index c3d66c97a1..9c532957a2 100644 --- a/utils/src/main/java/com/salesforce/apollo/causal/StampedClockValue.java +++ b/cryptography/src/main/java/com/salesforce/apollo/utils/Pair.java @@ -4,19 +4,10 @@ * SPDX-License-Identifier: BSD-3-Clause * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ -package com.salesforce.apollo.causal; - -import com.salesfoce.apollo.utils.proto.StampedClock; +package com.salesforce.apollo.utils; /** * @author hal.hildebrand - * */ -public interface StampedClockValue> extends ClockValue { - - T instant(); - - int sum(); - - StampedClock toStampedClock(); +public record Pair(A a, B b) { } diff --git a/cryptography/src/main/java/com/salesforce/apollo/utils/Utils.java b/cryptography/src/main/java/com/salesforce/apollo/utils/Utils.java new file mode 100644 index 0000000000..4159bdf435 --- /dev/null +++ b/cryptography/src/main/java/com/salesforce/apollo/utils/Utils.java @@ -0,0 +1,218 @@ +package com.salesforce.apollo.utils; + +import com.salesforce.apollo.crypto.Digest; +import com.salesforce.apollo.crypto.DigestAlgorithm; +import com.salesforce.apollo.crypto.SignatureAlgorithm; +import com.salesforce.apollo.crypto.cert.BcX500NameDnImpl; +import com.salesforce.apollo.crypto.cert.CertificateWithPrivateKey; +import com.salesforce.apollo.crypto.cert.Certificates; +import org.slf4j.Logger; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetAddress; +import java.net.ServerSocket; +import java.security.KeyPair; +import java.security.PublicKey; +import java.security.cert.X509Certificate; +import java.time.Instant; +import java.util.Collections; +import java.util.concurrent.Callable; +import java.util.function.Consumer; +import java.util.function.Supplier; + +import static com.salesforce.apollo.crypto.QualifiedBase64.qb64; + +/** + * @author hal.hildebrand + **/ +public class Utils { + + /** + * Copy the contents of the input stream to the output stream. It is the caller's responsibility to close the + * streams. + * + * @param is - source + * @param os - destination + * @param bufferSize - buffer size to use + * @throws IOException + */ + public static void copy(InputStream is, OutputStream os, int bufferSize) throws IOException { + copy(is, os, new byte[bufferSize]); + } + + /** + * Remove the file. If the file is a directory, the entire contents will be recursively removed. + * + * @param directoryOrFile + */ + public static void remove(File directoryOrFile) { + if (directoryOrFile.exists()) { + if (directoryOrFile.isDirectory()) { + for (File file : directoryOrFile.listFiles()) { + if (file.isDirectory()) { + remove(file); + } else { + if (!file.delete()) { + throw new IllegalStateException(String.format("Cannot delete [%s] ", file)); + } + } + } + } + if (!directoryOrFile.delete()) { + throw new IllegalStateException(String.format("Cannot delete [%s] ", directoryOrFile)); + } + } + } + + /** + * Clean the contents of a directory + * + * @param directory + */ + public static void clean(File directory) { + if (directory.exists()) { + if (directory.isDirectory()) { + for (File file : directory.listFiles()) { + if (file.isDirectory()) { + remove(file); + } else { + if (!file.delete()) { + throw new IllegalStateException(String.format("Cannot delete [%s] ", file)); + } + } + } + } + } + } + + /** + * Copy the contents of the input stream into the output stream using the default buffer size + * + * @param is + * @param os + * @throws IOException + */ + public static void copy(InputStream is, OutputStream os) throws IOException { + copy(is, os, 16 * 1024); + } + + /** + * Copy the contents of the input stream to the output stream. It is the caller's responsibility to close the + * streams. + * + * @param is - source + * @param os - destination + * @param buffer - byte buffer to use + * @throws IOException + */ + public static void copy(InputStream is, OutputStream os, byte[] buffer) throws IOException { + int len; + while ((len = is.read(buffer)) > 0) { + os.write(buffer, 0, len); + } + } + + public static boolean waitForCondition(int maxWaitTime, final int sleepTime, Supplier condition) { + long endTime = System.currentTimeMillis() + maxWaitTime; + while (System.currentTimeMillis() <= endTime) { + if (condition.get()) { + return true; + } + try { + Thread.sleep(sleepTime); + } catch (InterruptedException e) { + return false; + } + } + return false; + } + + public static boolean waitForCondition(int maxWaitTime, Supplier condition) { + return waitForCondition(maxWaitTime, 100, condition); + } + + public static CertificateWithPrivateKey getMember(Digest id) { + KeyPair keyPair = SignatureAlgorithm.ED_25519.generateKeyPair(); + var notBefore = Instant.now(); + var notAfter = Instant.now().plusSeconds(10_000); + String localhost = InetAddress.getLoopbackAddress().getHostName(); + X509Certificate generated = Certificates.selfSign(false, + encode(id, localhost, allocatePort(), keyPair.getPublic()), + keyPair, notBefore, notAfter, Collections.emptyList()); + return new CertificateWithPrivateKey(generated, keyPair.getPrivate()); + } + + public static CertificateWithPrivateKey getMember(int index) { + byte[] hash = new byte[32]; + hash[0] = (byte) index; + return getMember(new Digest(DigestAlgorithm.DEFAULT, hash)); + } + + public static BcX500NameDnImpl encode(Digest digest, String host, int port, PublicKey signingKey) { + return new BcX500NameDnImpl( + String.format("CN=%s, L=%s, UID=%s, DC=%s", host, port, qb64(digest), qb64(signingKey))); + } + + /** + * Find a free port for any local address + * + * @return the port number or -1 if none available + */ + public static int allocatePort() { + return allocatePort(null); + } + + /** + * Find a free port on the interface with the given address + * + * @return the port number or -1 if none available + */ + public static int allocatePort(InetAddress host) { + InetAddress address = host == null ? InetAddress.getLoopbackAddress() : host; + + try (ServerSocket socket = new ServerSocket(0, 0, address);) { + socket.setReuseAddress(true); + var localPort = socket.getLocalPort(); + socket.close(); + return localPort; + } catch (IOException e) { + return -1; + } + } + + public static Callable wrapped(Callable c, Logger log) { + return () -> { + try { + return c.call(); + } catch (Exception e) { + log.error("Error in call", e); + throw new IllegalStateException(e); + } + }; + } + + public static Consumer wrapped(Consumer c, Logger log) { + return t -> { + try { + c.accept(t); + } catch (Exception e) { + log.error("Error in call", e); + throw new IllegalStateException(e); + } + }; + } + + public static Runnable wrapped(Runnable r, Logger log) { + return () -> { + try { + r.run(); + } catch (Throwable e) { + log.error("Error in execution", e); + throw new IllegalStateException(e); + } + }; + } +} diff --git a/utils/src/test/java/com/salesforce/apollo/utils/bloomFilters/BloomFilterTest.java b/cryptography/src/test/java/com/salesforce/apollo/bloomFilters/BloomFilterTest.java similarity index 92% rename from utils/src/test/java/com/salesforce/apollo/utils/bloomFilters/BloomFilterTest.java rename to cryptography/src/test/java/com/salesforce/apollo/bloomFilters/BloomFilterTest.java index 1222c184ba..05c2d343e8 100644 --- a/utils/src/test/java/com/salesforce/apollo/utils/bloomFilters/BloomFilterTest.java +++ b/cryptography/src/test/java/com/salesforce/apollo/bloomFilters/BloomFilterTest.java @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ -package com.salesforce.apollo.utils.bloomFilters; +package com.salesforce.apollo.bloomFilters; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -12,12 +12,13 @@ import java.util.ArrayList; import java.util.List; +import com.salesforce.apollo.bloomFilters.BloomFilter; import org.junit.jupiter.api.Test; import com.salesforce.apollo.crypto.Digest; import com.salesforce.apollo.crypto.DigestAlgorithm; import com.salesforce.apollo.utils.Entropy; -import com.salesforce.apollo.utils.bloomFilters.BloomFilter.DigestBloomFilter; +import com.salesforce.apollo.bloomFilters.BloomFilter.DigestBloomFilter; /** * @author hal.hildebrand diff --git a/utils/src/test/java/com/salesforce/apollo/utils/bloomFilters/HashTest.java b/cryptography/src/test/java/com/salesforce/apollo/bloomFilters/HashTest.java similarity index 94% rename from utils/src/test/java/com/salesforce/apollo/utils/bloomFilters/HashTest.java rename to cryptography/src/test/java/com/salesforce/apollo/bloomFilters/HashTest.java index 4454b6546c..678d0eece7 100644 --- a/utils/src/test/java/com/salesforce/apollo/utils/bloomFilters/HashTest.java +++ b/cryptography/src/test/java/com/salesforce/apollo/bloomFilters/HashTest.java @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ -package com.salesforce.apollo.utils.bloomFilters; +package com.salesforce.apollo.bloomFilters; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -12,12 +12,13 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.stream.IntStream; +import com.salesforce.apollo.bloomFilters.Hash; import org.junit.jupiter.api.Test; import com.google.common.collect.ConcurrentHashMultiset; import com.salesforce.apollo.utils.Entropy; -import com.salesforce.apollo.utils.bloomFilters.Hash.BytesHasher; -import com.salesforce.apollo.utils.bloomFilters.Hash.IntHasher; +import com.salesforce.apollo.bloomFilters.Hash.BytesHasher; +import com.salesforce.apollo.bloomFilters.Hash.IntHasher; /** * @author hal.hildebrand diff --git a/utils/src/test/java/com/salesforce/apollo/crypto/EdDSAOperationsTests.java b/cryptography/src/test/java/com/salesforce/apollo/crypto/EdDSAOperationsTests.java similarity index 100% rename from utils/src/test/java/com/salesforce/apollo/crypto/EdDSAOperationsTests.java rename to cryptography/src/test/java/com/salesforce/apollo/crypto/EdDSAOperationsTests.java diff --git a/utils/src/test/java/com/salesforce/apollo/crypto/HexTests.java b/cryptography/src/test/java/com/salesforce/apollo/crypto/HexTests.java similarity index 100% rename from utils/src/test/java/com/salesforce/apollo/crypto/HexTests.java rename to cryptography/src/test/java/com/salesforce/apollo/crypto/HexTests.java diff --git a/utils/src/test/java/com/salesforce/apollo/crypto/QualifiedBase64Tests.java b/cryptography/src/test/java/com/salesforce/apollo/crypto/QualifiedBase64Tests.java similarity index 100% rename from utils/src/test/java/com/salesforce/apollo/crypto/QualifiedBase64Tests.java rename to cryptography/src/test/java/com/salesforce/apollo/crypto/QualifiedBase64Tests.java diff --git a/utils/src/test/java/com/salesforce/apollo/crypto/cert/TestCertificates.java b/cryptography/src/test/java/com/salesforce/apollo/crypto/cert/TestCertificates.java similarity index 100% rename from utils/src/test/java/com/salesforce/apollo/crypto/cert/TestCertificates.java rename to cryptography/src/test/java/com/salesforce/apollo/crypto/cert/TestCertificates.java diff --git a/utils/src/test/java/com/salesforce/apollo/utils/CheckSecureRandomConfig.java b/cryptography/src/test/java/com/salesforce/apollo/utils/CheckSecureRandomConfig.java similarity index 100% rename from utils/src/test/java/com/salesforce/apollo/utils/CheckSecureRandomConfig.java rename to cryptography/src/test/java/com/salesforce/apollo/utils/CheckSecureRandomConfig.java diff --git a/utils/src/test/java/com/salesforce/apollo/utils/SystemInfoTest.java b/cryptography/src/test/java/com/salesforce/apollo/utils/SystemInfoTest.java similarity index 100% rename from utils/src/test/java/com/salesforce/apollo/utils/SystemInfoTest.java rename to cryptography/src/test/java/com/salesforce/apollo/utils/SystemInfoTest.java diff --git a/utils/src/test/resources/logback-test.xml b/cryptography/src/test/resources/logback-test.xml similarity index 100% rename from utils/src/test/resources/logback-test.xml rename to cryptography/src/test/resources/logback-test.xml diff --git a/ethereal/pom.xml b/ethereal/pom.xml index 1e9aecfada..649591413a 100644 --- a/ethereal/pom.xml +++ b/ethereal/pom.xml @@ -12,10 +12,6 @@ Asynchonrous BFT Consensus - - com.salesforce.apollo - utils - com.salesforce.apollo memberships @@ -44,4 +40,4 @@ test - \ No newline at end of file + diff --git a/ethereal/src/main/java/com/salesforce/apollo/ethereal/Adder.java b/ethereal/src/main/java/com/salesforce/apollo/ethereal/Adder.java index b7854b39c2..318be3ac80 100644 --- a/ethereal/src/main/java/com/salesforce/apollo/ethereal/Adder.java +++ b/ethereal/src/main/java/com/salesforce/apollo/ethereal/Adder.java @@ -36,8 +36,8 @@ import com.salesforce.apollo.crypto.JohnHancock; import com.salesforce.apollo.crypto.Signer; import com.salesforce.apollo.utils.Entropy; -import com.salesforce.apollo.utils.bloomFilters.BloomFilter; -import com.salesforce.apollo.utils.bloomFilters.BloomFilter.DigestBloomFilter; +import com.salesforce.apollo.bloomFilters.BloomFilter; +import com.salesforce.apollo.bloomFilters.BloomFilter.DigestBloomFilter; /** * Implements the chain Reliable Broadcast of Aleph. diff --git a/ethereal/src/main/java/com/salesforce/apollo/ethereal/Dag.java b/ethereal/src/main/java/com/salesforce/apollo/ethereal/Dag.java index 8defc83f93..192334684c 100644 --- a/ethereal/src/main/java/com/salesforce/apollo/ethereal/Dag.java +++ b/ethereal/src/main/java/com/salesforce/apollo/ethereal/Dag.java @@ -31,8 +31,8 @@ import com.salesforce.apollo.crypto.Digest; import com.salesforce.apollo.ethereal.PreUnit.DecodedId; import com.salesforce.apollo.membership.Context; -import com.salesforce.apollo.utils.bloomFilters.BloomFilter; -import com.salesforce.apollo.utils.bloomFilters.BloomFilter.DigestBloomFilter; +import com.salesforce.apollo.bloomFilters.BloomFilter; +import com.salesforce.apollo.bloomFilters.BloomFilter.DigestBloomFilter; /** * @author hal.hildebrand diff --git a/fireflies/src/main/java/com/salesforce/apollo/fireflies/View.java b/fireflies/src/main/java/com/salesforce/apollo/fireflies/View.java index cc571ee36a..0b2ec8fcfa 100644 --- a/fireflies/src/main/java/com/salesforce/apollo/fireflies/View.java +++ b/fireflies/src/main/java/com/salesforce/apollo/fireflies/View.java @@ -37,9 +37,9 @@ import com.salesforce.apollo.stereotomy.EventValidation; import com.salesforce.apollo.stereotomy.identifier.SelfAddressingIdentifier; import com.salesforce.apollo.utils.Entropy; -import com.salesforce.apollo.utils.RoundScheduler; +import com.salesforce.apollo.membership.RoundScheduler; import com.salesforce.apollo.utils.Utils; -import com.salesforce.apollo.utils.bloomFilters.BloomFilter; +import com.salesforce.apollo.bloomFilters.BloomFilter; import io.grpc.Status; import io.grpc.StatusRuntimeException; import io.grpc.stub.StreamObserver; diff --git a/fireflies/src/main/java/com/salesforce/apollo/fireflies/ViewManagement.java b/fireflies/src/main/java/com/salesforce/apollo/fireflies/ViewManagement.java index aef7dbacb9..1e3011aeee 100644 --- a/fireflies/src/main/java/com/salesforce/apollo/fireflies/ViewManagement.java +++ b/fireflies/src/main/java/com/salesforce/apollo/fireflies/ViewManagement.java @@ -47,7 +47,7 @@ import com.salesforce.apollo.membership.ReservoirSampler; import com.salesforce.apollo.stereotomy.EventCoordinates; import com.salesforce.apollo.utils.Entropy; -import com.salesforce.apollo.utils.bloomFilters.BloomFilter; +import com.salesforce.apollo.bloomFilters.BloomFilter; import io.grpc.Status; import io.grpc.StatusRuntimeException; diff --git a/utils/src/main/java/com/salesforce/apollo/utils/RoundScheduler.java b/memberships/src/main/java/com/salesforce/apollo/membership/RoundScheduler.java similarity index 99% rename from utils/src/main/java/com/salesforce/apollo/utils/RoundScheduler.java rename to memberships/src/main/java/com/salesforce/apollo/membership/RoundScheduler.java index b749b3c18e..e1021cca48 100644 --- a/utils/src/main/java/com/salesforce/apollo/utils/RoundScheduler.java +++ b/memberships/src/main/java/com/salesforce/apollo/membership/RoundScheduler.java @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ -package com.salesforce.apollo.utils; +package com.salesforce.apollo.membership; import java.util.ArrayList; import java.util.List; diff --git a/memberships/src/main/java/com/salesforce/apollo/membership/messaging/rbc/ReliableBroadcaster.java b/memberships/src/main/java/com/salesforce/apollo/membership/messaging/rbc/ReliableBroadcaster.java index 64cecc5a4c..71c04ee8b2 100644 --- a/memberships/src/main/java/com/salesforce/apollo/membership/messaging/rbc/ReliableBroadcaster.java +++ b/memberships/src/main/java/com/salesforce/apollo/membership/messaging/rbc/ReliableBroadcaster.java @@ -24,8 +24,8 @@ import com.salesforce.apollo.membership.messaging.rbc.comms.ReliableBroadcast; import com.salesforce.apollo.ring.RingCommunications; import com.salesforce.apollo.utils.Entropy; -import com.salesforce.apollo.utils.bloomFilters.BloomFilter; -import com.salesforce.apollo.utils.bloomFilters.BloomFilter.DigestBloomFilter; +import com.salesforce.apollo.bloomFilters.BloomFilter; +import com.salesforce.apollo.bloomFilters.BloomFilter.DigestBloomFilter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/model/src/main/java/com/salesforce/apollo/model/SubDomain.java b/model/src/main/java/com/salesforce/apollo/model/SubDomain.java index 36c0d84bb0..ee22d0426d 100644 --- a/model/src/main/java/com/salesforce/apollo/model/SubDomain.java +++ b/model/src/main/java/com/salesforce/apollo/model/SubDomain.java @@ -23,8 +23,8 @@ import com.salesforce.apollo.model.comms.DelegationService; import com.salesforce.apollo.ring.RingCommunications; import com.salesforce.apollo.utils.Entropy; -import com.salesforce.apollo.utils.bloomFilters.BloomFilter; -import com.salesforce.apollo.utils.bloomFilters.BloomFilter.DigestBloomFilter; +import com.salesforce.apollo.bloomFilters.BloomFilter; +import com.salesforce.apollo.bloomFilters.BloomFilter.DigestBloomFilter; import org.h2.mvstore.MVMap; import org.h2.mvstore.MVStore; import org.slf4j.Logger; @@ -36,7 +36,6 @@ import java.util.Map; import java.util.Optional; import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; diff --git a/pom.xml b/pom.xml index d608ec6dcd..398b499d16 100644 --- a/pom.xml +++ b/pom.xml @@ -1,12 +1,13 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.salesforce.apollo apollo.app 0.0.1-SNAPSHOT pom Apollo Umbrella App + fireflies protocols @@ -14,7 +15,6 @@ memberships tron stereotomy - utils ethereal choam model @@ -22,14 +22,14 @@ schemas demo stereotomy-services - thoth liquibase-deterministic grpc gorgoneion gorgoneion-client + cryptography + 1.9.5 2.15.2 @@ -169,11 +169,6 @@ stereotomy ${project.version} - - com.salesforce.apollo - utils - ${project.version} - com.salesforce.apollo choam @@ -259,6 +254,11 @@ demesnes ${project.version} + + com.salesforce.apollo + cryptography + ${project.version} + com.salesforce.apollo isolates @@ -629,7 +629,7 @@ [3.8.1,) - + [19,) @@ -649,7 +649,7 @@ org.apache.maven.plugins maven-antrun-plugin - 3.1.0 + 3.1.0 satisfy-liquibase @@ -657,9 +657,9 @@ + dir="${project.build.directory}/test-classes"/> + dir="${project.build.directory}/classes"/> @@ -746,11 +746,14 @@ ${project.basedir}/src/main/proto - ${project.basedir}/target/generated-sources/protobuf/grpc-java + ${project.basedir}/target/generated-sources/protobuf/grpc-java + - ${project.basedir}/target/generated-sources/protobuf/java + ${project.basedir}/target/generated-sources/protobuf/java + - ${project.basedir}/target/generated-sources/jooq + ${project.basedir}/target/generated-sources/jooq + @@ -764,11 +767,14 @@ ${project.basedir}/src/test/proto - ${project.basedir}/target/generated-test-sources/protobuf/grpc-java + ${project.basedir}/target/generated-test-sources/protobuf/grpc-java + - ${project.basedir}/target/generated-test-sources/protobuf/java + ${project.basedir}/target/generated-test-sources/protobuf/java + - ${project.basedir}/target/generated-test-sources/jooq + ${project.basedir}/target/generated-test-sources/jooq + @@ -780,10 +786,12 @@ 0.6.1 - com.google.protobuf:protoc:${protobuf.version}:exe:${os.detected.classifier} + com.google.protobuf:protoc:${protobuf.version}:exe:${os.detected.classifier} + grpc-java - io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier} + io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier} + @@ -799,4 +807,4 @@ - \ No newline at end of file + diff --git a/protocols/pom.xml b/protocols/pom.xml index 44b4b52c72..db29ffde97 100644 --- a/protocols/pom.xml +++ b/protocols/pom.xml @@ -12,7 +12,7 @@ com.salesforce.apollo - utils + cryptography io.grpc @@ -109,4 +109,4 @@ - \ No newline at end of file + diff --git a/utils/src/main/java/com/salesforce/apollo/utils/DelegatingJdbcConnector.java b/sql-state/src/main/java/com/salesforce/apollo/state/DelegatingJdbcConnector.java similarity index 99% rename from utils/src/main/java/com/salesforce/apollo/utils/DelegatingJdbcConnector.java rename to sql-state/src/main/java/com/salesforce/apollo/state/DelegatingJdbcConnector.java index 853a755cd6..e90067cece 100644 --- a/utils/src/main/java/com/salesforce/apollo/utils/DelegatingJdbcConnector.java +++ b/sql-state/src/main/java/com/salesforce/apollo/state/DelegatingJdbcConnector.java @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ -package com.salesforce.apollo.utils; +package com.salesforce.apollo.state; import java.sql.Array; import java.sql.Blob; diff --git a/sql-state/src/main/java/com/salesforce/apollo/state/SqlStateMachine.java b/sql-state/src/main/java/com/salesforce/apollo/state/SqlStateMachine.java index 6a896ff1fe..140f19c2fe 100644 --- a/sql-state/src/main/java/com/salesforce/apollo/state/SqlStateMachine.java +++ b/sql-state/src/main/java/com/salesforce/apollo/state/SqlStateMachine.java @@ -21,10 +21,9 @@ import com.salesforce.apollo.crypto.QualifiedBase64; import com.salesforce.apollo.state.Mutator.BatchedTransactionException; import com.salesforce.apollo.state.liquibase.*; -import com.salesforce.apollo.utils.DelegatingJdbcConnector; import com.salesforce.apollo.utils.Entropy; import com.salesforce.apollo.utils.Utils; -import com.salesforce.apollo.utils.bloomFilters.Hash.DigestHasher; +import com.salesforce.apollo.bloomFilters.Hash.DigestHasher; import deterministic.org.h2.api.ErrorCode; import deterministic.org.h2.engine.SessionLocal; import deterministic.org.h2.jdbc.JdbcConnection; diff --git a/sql-state/src/main/java/com/salesforce/apollo/state/liquibase/LiquibaseConnection.java b/sql-state/src/main/java/com/salesforce/apollo/state/liquibase/LiquibaseConnection.java index 4c23e1481c..9fe6fb51a2 100644 --- a/sql-state/src/main/java/com/salesforce/apollo/state/liquibase/LiquibaseConnection.java +++ b/sql-state/src/main/java/com/salesforce/apollo/state/liquibase/LiquibaseConnection.java @@ -9,7 +9,7 @@ import java.sql.Connection; import java.sql.SQLException; -import com.salesforce.apollo.utils.DelegatingJdbcConnector; +import com.salesforce.apollo.state.DelegatingJdbcConnector; /** * @author hal.hildebrand diff --git a/sql-state/src/test/java/com/salesforce/apollo/state/ScriptTest.java b/sql-state/src/test/java/com/salesforce/apollo/state/ScriptTest.java index 66c44685fe..f4075eda4e 100644 --- a/sql-state/src/test/java/com/salesforce/apollo/state/ScriptTest.java +++ b/sql-state/src/test/java/com/salesforce/apollo/state/ScriptTest.java @@ -6,10 +6,16 @@ */ package com.salesforce.apollo.state; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; +import com.salesfoce.apollo.choam.proto.Transaction; +import com.salesfoce.apollo.state.proto.Txn; +import com.salesforce.apollo.crypto.Digest; +import com.salesforce.apollo.crypto.DigestAlgorithm; +import org.junit.jupiter.api.Test; +import java.io.BufferedReader; import java.io.File; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; @@ -17,18 +23,13 @@ import java.util.Collections; import java.util.Properties; import java.util.concurrent.CompletableFuture; +import java.util.stream.Collectors; -import org.junit.jupiter.api.Test; - -import com.salesfoce.apollo.choam.proto.Transaction; -import com.salesfoce.apollo.state.proto.Txn; -import com.salesforce.apollo.crypto.Digest; -import com.salesforce.apollo.crypto.DigestAlgorithm; -import com.salesforce.apollo.utils.Utils; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; /** * @author hal.hildebrand - * */ public class ScriptTest { @@ -41,9 +42,15 @@ public void smoke() throws Exception { createAndInsert(connection); connection.commit(); Txn txn = Txn.newBuilder() - .setScript(new Mutator(null, - machine.getSession()).callScript("test.DbAccess", "call", - Utils.getDocument(getClass().getResourceAsStream("/scripts/dbaccess.java")))) + .setScript(new Mutator(null, machine.getSession()).callScript("test.DbAccess", "call", + new BufferedReader( + new InputStreamReader( + getClass().getResourceAsStream( + "/scripts/dbaccess.java"), + StandardCharsets.UTF_8)).lines() + .collect( + Collectors.joining( + "\n")))) .build(); CompletableFuture completion = new CompletableFuture<>(); machine.getExecutor() diff --git a/stereotomy/pom.xml b/stereotomy/pom.xml index 8eec06f03c..5b7c20e4ad 100644 --- a/stereotomy/pom.xml +++ b/stereotomy/pom.xml @@ -20,7 +20,7 @@ com.salesforce.apollo - utils + cryptography org.jooq @@ -252,4 +252,4 @@ - \ No newline at end of file + diff --git a/thoth/src/main/java/com/salesforce/apollo/thoth/KerlDHT.java b/thoth/src/main/java/com/salesforce/apollo/thoth/KerlDHT.java index bf136d6071..8bc7d0038a 100644 --- a/thoth/src/main/java/com/salesforce/apollo/thoth/KerlDHT.java +++ b/thoth/src/main/java/com/salesforce/apollo/thoth/KerlDHT.java @@ -48,8 +48,7 @@ import com.salesforce.apollo.thoth.grpc.reconciliation.ReconciliationServer; import com.salesforce.apollo.thoth.grpc.reconciliation.ReconciliationService; import com.salesforce.apollo.utils.Entropy; -import com.salesforce.apollo.utils.LoggingOutputStream; -import com.salesforce.apollo.utils.LoggingOutputStream.LogLevel; +import com.salesforce.apollo.thoth.LoggingOutputStream.LogLevel; import liquibase.Liquibase; import liquibase.Scope; import liquibase.Scope.Attr; diff --git a/thoth/src/main/java/com/salesforce/apollo/thoth/KerlSpace.java b/thoth/src/main/java/com/salesforce/apollo/thoth/KerlSpace.java index ac51271d9d..0a3008fbbe 100644 --- a/thoth/src/main/java/com/salesforce/apollo/thoth/KerlSpace.java +++ b/thoth/src/main/java/com/salesforce/apollo/thoth/KerlSpace.java @@ -23,8 +23,8 @@ import com.salesforce.apollo.stereotomy.event.protobuf.AttachmentEventImpl; import com.salesforce.apollo.stereotomy.event.protobuf.ProtobufEventFactory; import com.salesforce.apollo.stereotomy.identifier.Identifier; -import com.salesforce.apollo.utils.bloomFilters.BloomFilter; -import com.salesforce.apollo.utils.bloomFilters.BloomFilter.DigestBloomFilter; +import com.salesforce.apollo.bloomFilters.BloomFilter; +import com.salesforce.apollo.bloomFilters.BloomFilter.DigestBloomFilter; import org.h2.jdbcx.JdbcConnectionPool; import org.jooq.DSLContext; import org.jooq.Record1; diff --git a/utils/src/main/java/com/salesforce/apollo/utils/LoggingOutputStream.java b/thoth/src/main/java/com/salesforce/apollo/thoth/LoggingOutputStream.java similarity index 97% rename from utils/src/main/java/com/salesforce/apollo/utils/LoggingOutputStream.java rename to thoth/src/main/java/com/salesforce/apollo/thoth/LoggingOutputStream.java index 5092a9befc..4b7e3b8008 100644 --- a/utils/src/main/java/com/salesforce/apollo/utils/LoggingOutputStream.java +++ b/thoth/src/main/java/com/salesforce/apollo/thoth/LoggingOutputStream.java @@ -5,7 +5,7 @@ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ -package com.salesforce.apollo.utils; +package com.salesforce.apollo.thoth; import java.io.ByteArrayOutputStream; import java.io.OutputStream; diff --git a/thoth/src/test/java/com/salesforce/apollo/thoth/KerlSpaceTest.java b/thoth/src/test/java/com/salesforce/apollo/thoth/KerlSpaceTest.java index 5e44c3c87f..94e52e56de 100644 --- a/thoth/src/test/java/com/salesforce/apollo/thoth/KerlSpaceTest.java +++ b/thoth/src/test/java/com/salesforce/apollo/thoth/KerlSpaceTest.java @@ -12,7 +12,7 @@ import com.salesforce.apollo.stereotomy.StereotomyImpl; import com.salesforce.apollo.stereotomy.db.UniKERLDirectPooled; import com.salesforce.apollo.stereotomy.mem.MemKeyStore; -import com.salesforce.apollo.utils.bloomFilters.BloomFilter; +import com.salesforce.apollo.bloomFilters.BloomFilter; import liquibase.Liquibase; import liquibase.database.core.H2Database; import liquibase.exception.LiquibaseException; diff --git a/utils/README.md b/utils/README.md deleted file mode 100644 index e24f58463d..0000000000 --- a/utils/README.md +++ /dev/null @@ -1,2 +0,0 @@ -# Apollo Utils -Base crypto and utilies. Causal structures, Bloom Filters, etc. diff --git a/utils/src/main/java/com/salesforce/apollo/causal/BloomClock.java b/utils/src/main/java/com/salesforce/apollo/causal/BloomClock.java deleted file mode 100644 index 69786ec5f4..0000000000 --- a/utils/src/main/java/com/salesforce/apollo/causal/BloomClock.java +++ /dev/null @@ -1,483 +0,0 @@ -/* - * Copyright (c) 2021, salesforce.com, inc. - * All rights reserved. - * SPDX-License-Identifier: BSD-3-Clause - * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause - */ -package com.salesforce.apollo.causal; - -import java.util.Arrays; -import java.util.Collection; -import java.util.Objects; -import java.util.stream.IntStream; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.protobuf.ByteString; -import com.salesfoce.apollo.utils.proto.BloomeClock; -import com.salesfoce.apollo.utils.proto.Clock; -import com.salesfoce.apollo.utils.proto.StampedBloomeClock; -import com.salesforce.apollo.crypto.Digest; -import com.salesforce.apollo.utils.BUZ; -import com.salesforce.apollo.utils.Entropy; -import com.salesforce.apollo.utils.bloomFilters.Hash; - -/** - * - * The BloomClock implements the scheme outlined in the excellent paper By Lum - * Ramabaja, The Bloom Clock - *

- * The BloomClock represents a partial ordering that can be used in the same - * fashion as Vector Clocks. The Bloom Clock tracks histories of observed - * Digests through a counting bloom filter. Bloom clocks can be compared to see - * if one preceded the other. Because the Bloom Clock is based on a - * probabalistic data structure - i.e. the bloom filter - there are false - * positives that can result when comparing two Bloom Clocks. - *

- * This implementation is based on a 4 bit counting bloom filter. To handle - * overflow a Long prefix is kept. Periodically in insertion, the current counts - * will be renormalized, subtracting a common minimum and adding this to the - * prefix. This allows the Bloom Clock to track approximately 2^64 events - * - * @author hal.hildebrand - * - */ -public class BloomClock implements ClockValue { - - record ComparisonResult(int comparison, double fpr) {} - - record Comparison(int compared, int sumA, int sumB) {} - - public static long DEFAULT_GOOD_SEED = Entropy.nextBitsStreamLong(); - public final static int DEFAULT_K = 3; - public static final int DEFAULT_M = 200; - public static int MASK = 0x0F; - - private final static Logger log = LoggerFactory.getLogger(BloomClock.class); - - public static String print(BloomClockValue clock) { - StringBuilder buff = new StringBuilder(); - if (Long.compareUnsigned(clock.prefix(), 0) > 0) { - buff.append("("); - buff.append(Long.toUnsignedString(clock.prefix())); - buff.append(")"); - } - buff.append("["); - boolean comma = false; - byte[] counts = clock.counts(); - for (int i = 0; i < m(counts); i++) { - if (comma) { - buff.append(','); - } - buff.append(count(i, counts)); - comma = true; - } - buff.append("]"); - return buff.toString(); - } - - public static boolean validate(int m, byte[] counts) { - return m == m(counts); - } - - static int happenedBefore(double fpr, long abcPrefix, byte[] abcCounts, long bbcPrefix, byte[] bbcCounts) { - assert abcCounts.length == bbcCounts.length; - - int sumA = 0; - int sumB = 0; - int aGreater = 0; - int bGreater = 0; - - int aBias = 0; // only one is > 0 if any - int bBias = 0; - - int prefixCompare = Long.compareUnsigned(abcPrefix, bbcPrefix); - int m = m(abcCounts); - if (prefixCompare < 0) { - long preDiff = bbcPrefix - abcPrefix; - if (Long.compareUnsigned(preDiff, MASK) > 0) { - return -1; - } - bBias = (int) (preDiff & MASK); - } else if (prefixCompare > 0) { - long preDiff = abcPrefix - bbcPrefix; - if (Long.compareUnsigned(preDiff, MASK) > 0) { - return 1; - } - aBias = (int) (preDiff & MASK); - } - - for (int i = 0; i < m; i++) { - int a = count(i, abcCounts) + aBias; - sumA += a; - int b = count(i, bbcCounts) + bBias; - sumB += b; - if (a < b) { - bGreater++; - } else if (a > b) { - aGreater++; - } - } - - // check for equality - if (aGreater == 0 & bGreater == 0) { - return 0; - } - - // A and B are not comparable as both are greater in some count than the other - if (aGreater != 0 & bGreater != 0) { - return 0; - } - - // one of A or B == 0 - - // is A > B - if (bGreater == 0) { // all A >= B and at least 1 count of A is > B - double cFPR = falsePositiveRate(sumA, sumB, m(abcCounts)); - assert cFPR >= 0.0; - if (cFPR <= fpr) { - return 1; // fell under the threshold, so it's not a false positive - } - return 0; // consider this a false positive, therefore uncomparable - } - - // all A <= B - double cFPR = falsePositiveRate(sumA, sumB, m(abcCounts)); - assert cFPR >= 0.0; - if (cFPR <= fpr) { - return -1; // fell under the threshold, so it's not a false positive - } - return 0; // consider this a false positive, therefore uncomparable - - } - - static int count(int index, byte[] counts) { - return counts[index] & MASK; - } - - static double falsePositiveRate(int sumA, int sumB, int m) { - double X = sumB; - double Y = sumA; - double M = m; - return Math.pow(1.0 - Math.pow(1.0 - (1.0 / M), X), Y); - } - - static double falsePositiveRate(Comparison c, int m) { - double x = Math.min(c.sumA(), c.sumB()); - double y = Math.max(c.sumA(), c.sumB()); - return Math.pow(1 - Math.pow(1.0 - (1.0 / m), x), y); - } - - static int m(byte[] counts) { - return counts.length; - } - - static Hash newHash(int k, int m) { - return new Hash<>(BUZ.buzhash(0), k, m) { - @Override - protected Hasher newHasher() { - return new DigestHasher(); - } - }; - } - - private final byte[] counts; // two cells per byte, giving 4 bits per cell - - private final Hash hash; - - private long prefix = 0; - - public BloomClock() { - this(DEFAULT_K, DEFAULT_M); - } - - public BloomClock(BloomClock clock, byte[] initialValues) { - this(clock.prefix, clock.hash, initialValues); - } - - public BloomClock(BloomeClock clock) { - this(clock.getPrefix(), newHash(clock.getK(), clock.getCounts().size()), clock.getCounts().toByteArray()); - } - - public BloomClock(int[] initialValues) { - this(DEFAULT_GOOD_SEED, initialValues, DEFAULT_K); - } - - public BloomClock(byte[] counts, int k) { - this.counts = counts; - this.hash = newHash(k, counts.length); - } - - public BloomClock(Clock clock, int k, int m) { - byte[] initialCounts = clock.getCounts().toByteArray(); - if (m(initialCounts) != m) { - throw new IllegalArgumentException("invalid counts.length: " + m(initialCounts) + " expected: " + m); - } - prefix = clock.getPrefix(); - counts = initialCounts; - hash = newHash(k, m); - } - - public BloomClock(int k, int m) { - counts = new byte[m]; - hash = newHash(k, m); - } - - /** - * - * @param seed - the seed for the Hash function - * @param initialValues - initial values of the clock - * @param k - number of hashes - */ - public BloomClock(long seed, int[] initialValues, int k) { - if (IntStream.of(initialValues).max().getAsInt() > MASK) { - throw new IllegalArgumentException("initial values contain values > " + MASK); - } - counts = new byte[initialValues.length]; - hash = newHash(k, initialValues.length); - int min = 0; - prefix += min; - if (IntStream.of(initialValues).map(i -> i - min).max().getAsInt() > MASK) { - throw new IllegalArgumentException("Cannot represent with a valid clock value. Overflow."); - } - for (int i = 0; i < initialValues.length; i = i + 1) { - set(i, initialValues[i] - min); - } - } - - public BloomClock(StampedBloomeClock clock) { - this(clock.getClock().getPrefix(), newHash(clock.getClock().getK(), clock.getClock().getCounts().size()), - clock.getClock().getCounts().toByteArray()); - } - - private BloomClock(long prefix, Hash hash, byte[] counts) { - this.hash = hash; - this.counts = counts; - this.prefix = prefix; - } - - /** - * Add a digest to this clock. This should be done only once per unique digest. - */ - public void add(Digest digest) { - boolean roll = false; - for (int hash : hash.hashes(digest)) { - int count = count(hash); - if (count + 1 == MASK) { - roll = true; - } - inc(hash); - } - if (roll) { - rollPrefix(); - } - } - - public void addAll(Collection digests) { - digests.forEach(d -> add(d)); - } - - @Override - public BloomClock clone() { - return new BloomClock(prefix, hash.clone(), Arrays.copyOf(counts, counts.length)); - } - - @Override - public int compareTo(double fpr, ClockValue b) { - BloomClockValue bbc = b.toBloomClockValue(); - return happenedBefore(fpr, prefix, counts, bbc.prefix(), bbc.counts()); - } - - /** - * Answer an immutable ClockValue of the current state of the receiver - */ - public BloomClockValue current() { - return new BloomClockValue(prefix, Arrays.copyOf(counts, counts.length)); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!(obj instanceof BloomClock)) { - return false; - } - BloomClock other = (BloomClock) obj; - return Arrays.equals(counts, other.counts) && prefix == other.prefix; - } - - public double fpp(int n) { - return hash.fpp(n); - } - - public long getPrefix() { - return prefix; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + Arrays.hashCode(counts); - result = prime * result + Objects.hash(prefix); - return result; - } - - public boolean isOrigin() { - if (prefix != 0) { - return false; - } - for (int i = 0; i < counts.length; i++) { - if (counts[i] != 0) { - return false; - } - } - return true; - } - - /** - * Merge the specified clock with the receiver. The receiver's new state is the - * max(receiver, clockB) - * - * @return the immutable ClockValue representing the merged state of the - * receiver - */ - public ClockValue merge(ClockValue clockB) { - BloomClockValue bbc = clockB.toBloomClockValue(); - - if (counts.length != bbc.counts().length) { - throw new IllegalArgumentException("Cannot merge as this clock has m: " + hash.m + " and B has m: " - + bbc.m()); - } - - // only one is > 0 if any - int aBias = 0; - int bBias = 0; - - // Merge prefixes - int prefixCompare = Long.compareUnsigned(prefix, bbc.prefix()); - if (prefixCompare < 0) { - long preDiff = bbc.prefix() - prefix; - prefix = bbc.prefix(); - if (Long.compareUnsigned(preDiff, MASK) > 0) { - for (int i = 0; i < counts.length; i++) { - counts[i] = bbc.counts()[i]; - } - return this; - } - bBias = (int) (preDiff & MASK); - } else if (prefixCompare > 0) { - long preDiff = prefix - bbc.prefix(); - if (Long.compareUnsigned(preDiff, MASK) > 0) { - return this; - } - aBias = (int) (preDiff & MASK); - } - - int overall = 0; - for (int i = 0; i < hash.m; i++) { - int a = count(i) + aBias; - int b = count(i, bbc.counts()) + bBias; - - int max = Math.max(a, b) - aBias - bBias; - set(i, max); - overall = Math.max(max, overall); - } - if (overall == 0xFF) { - rollPrefix(); - } - return this; - } - - public void reset() { - for (int i = 0; i < counts.length; i++) { - counts[i] = 0; - } - prefix = 0; - } - - public int sum() { - int sum = 0; - for (int i = 0; i < hash.m; i++) { - sum += count(i); - } - return sum; - } - - @Override - public BloomClockValue toBloomClockValue() { - return new BloomClockValue(prefix, counts); - } - - public BloomeClock toBloomeClock() { - return BloomeClock.newBuilder().setPrefix(prefix).setK(hash.k).setCounts(ByteString.copyFrom(counts)).build(); - } - - @Override - public Clock toClock() { - return Clock.newBuilder().setPrefix(prefix).setCounts(ByteString.copyFrom(counts)).build(); - } - - @Override - public String toString() { - StringBuilder buff = new StringBuilder(); - if (Long.compareUnsigned(prefix, 0) > 0) { - buff.append("("); - buff.append(Long.toUnsignedString(prefix)); - buff.append(")"); - } - buff.append("["); - boolean comma = false; - for (int i = 0; i < hash.m; i++) { - if (comma) { - buff.append(','); - } - buff.append(count(i)); - comma = true; - } - buff.append("]"); - return buff.toString(); - } - - public boolean validate(StampedBloomeClock clock) { - BloomeClock vector = clock.getClock(); - return hash.k == vector.getK() && counts.length == vector.getCounts().size(); - } - - private int count(int index) { - return count(index, counts); - } - - private void inc(int index) { - counts[index] += 1; - } - - private void rollPrefix() { - int min = MASK; - for (int i = 0; i < hash.m; i++) { - int count = count(i); - if (count == 0x00) { - log.trace("Overflow"); - return; - } - min = Math.min(min, count); - } - if (prefix == -1L) { - log.info("Prefix already at max, you win the internet"); - return; - } - prefix += min; - for (int i = 0; i < counts.length; i++) { - set(i, count(i) - min); - } - } - - private void set(int index, int value) { - if (value < 0 || value > MASK) { - throw new IllegalArgumentException(); - } - counts[index] = (byte) (value & MASK); - } -} diff --git a/utils/src/main/java/com/salesforce/apollo/causal/BloomClockValue.java b/utils/src/main/java/com/salesforce/apollo/causal/BloomClockValue.java deleted file mode 100644 index 7d869acf07..0000000000 --- a/utils/src/main/java/com/salesforce/apollo/causal/BloomClockValue.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2021, salesforce.com, inc. - * All rights reserved. - * SPDX-License-Identifier: BSD-3-Clause - * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause - */ -package com.salesforce.apollo.causal; - -import static com.salesforce.apollo.causal.BloomClock.count; - -import com.google.protobuf.ByteString; -import com.salesfoce.apollo.utils.proto.Clock; - -/** - * @author hal.hildebrand - * - */ - -public record BloomClockValue(long prefix, byte[] counts) implements ClockValue { - - @Override - public int compareTo(double fpr, ClockValue b) { - var bcv = b.toBloomClockValue(); - return happenedBefore(fpr, bcv.prefix, bcv.counts); - } - - public int happenedBefore(double fpr, long bbcPrefix, byte[] bbcCounts) { - return BloomClock.happenedBefore(fpr, prefix, counts, bbcPrefix, bbcCounts); - } - - public int m() { - return BloomClock.m(counts); - } - - @Override - public Clock toClock() { - return Clock.newBuilder().setPrefix(prefix).setCounts(ByteString.copyFrom(counts)).build(); - } - - @Override - public BloomClockValue toBloomClockValue() { - return this; - } - - public int sum() { - int sum = 0; - for (int i = 0; i < m(); i++) { - sum += count(i, counts); - } - return sum; - } -} diff --git a/utils/src/main/java/com/salesforce/apollo/causal/CausalClock.java b/utils/src/main/java/com/salesforce/apollo/causal/CausalClock.java deleted file mode 100644 index bf6081c370..0000000000 --- a/utils/src/main/java/com/salesforce/apollo/causal/CausalClock.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2021, salesforce.com, inc. - * All rights reserved. - * SPDX-License-Identifier: BSD-3-Clause - * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause - */ -package com.salesforce.apollo.causal; - -import java.util.Collection; - -import com.salesfoce.apollo.utils.proto.StampedClock; -import com.salesforce.apollo.crypto.Digest; - -/** - * @author hal.hildebrand - * - */ -public interface CausalClock> extends StampedClockValue { - StampedClockValue current(); - - StampedClockValue merge(StampedClockValue b); - - StampedClockValue observe(Digest digest); - - T observeAll(Collection digests); - - void reset(); - - StampedClock stamp(); -} diff --git a/utils/src/main/java/com/salesforce/apollo/causal/ClockValue.java b/utils/src/main/java/com/salesforce/apollo/causal/ClockValue.java deleted file mode 100644 index b59d97c669..0000000000 --- a/utils/src/main/java/com/salesforce/apollo/causal/ClockValue.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2021, salesforce.com, inc. - * All rights reserved. - * SPDX-License-Identifier: BSD-3-Clause - * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause - */ -package com.salesforce.apollo.causal; - -import com.salesfoce.apollo.utils.proto.Clock; - -/** - * @author hal.hildebrand - * - */ -public interface ClockValue { - - static BloomClockValue of(Clock clock) { - byte[] counts = clock.getCounts().toByteArray(); - return new BloomClockValue(clock.getPrefix(), counts); - } - - BloomClockValue toBloomClockValue(); - - int compareTo(double fbr, ClockValue b); - - Clock toClock(); -} diff --git a/utils/src/main/java/com/salesforce/apollo/causal/ClockValueComparator.java b/utils/src/main/java/com/salesforce/apollo/causal/ClockValueComparator.java deleted file mode 100644 index 89153eb17f..0000000000 --- a/utils/src/main/java/com/salesforce/apollo/causal/ClockValueComparator.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2021, salesforce.com, inc. - * All rights reserved. - * SPDX-License-Identifier: BSD-3-Clause - * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause - */ -package com.salesforce.apollo.causal; - -import java.util.Comparator; - -/** - * @author hal.hildebrand - * - */ - -/** - * A comparator for Bloom Clock values. Because the Bloom Clock is a - * probabalistic data structure, this comparator requires a provided false - * positive rate (FPR). This FPR applies when clock A is compared to clock B - * and the determination is that A proceeds B - this is the equivalent of - * "contains" in a vanilla Bloom Filter. The "proceeds", or "contains" - * determination is however probabalistic in that there is still a possibility - * this is a false positive (the past is "contained" in the present and future, - * so the FPR applies to the "proceeded" relationship). - *

- * - */ -public class ClockValueComparator implements Comparator { - private final double fpr; - - /** - * - * @param fpr - the False Positive Rate. Acceptable probability from 0.0 -> 1.0 - * of a false positive when determining precidence. - */ - public ClockValueComparator(double fpr) { - this.fpr = fpr; - } - - /** - * Provides comparison between two Bloom Clock values. The comparator has a - * false positive threshold that determines the acceptable threshold of - * assurance that clock A proceeds clock B. - *

- * If clock A is ordered after clock B, then this function returns 1 - *

- * If clocks A and B are not comparable, i.e. they are "simultaneous", then this - * function returns 0. - *

- * If clock A proceeds B within this comparator's false positive rate, then this - * function returns -1. - */ - @Override - public int compare(ClockValue a, ClockValue b) { - return a.compareTo(fpr, b); - } - - @Override - public String toString() { - return "CVC [fpr=" + fpr + "]"; - } - -} diff --git a/utils/src/main/java/com/salesforce/apollo/causal/IntCausalClock.java b/utils/src/main/java/com/salesforce/apollo/causal/IntCausalClock.java deleted file mode 100644 index fb3dee53b9..0000000000 --- a/utils/src/main/java/com/salesforce/apollo/causal/IntCausalClock.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2021, salesforce.com, inc. - * All rights reserved. - * SPDX-License-Identifier: BSD-3-Clause - * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause - */ -package com.salesforce.apollo.causal; - -import static com.salesforce.apollo.utils.Utils.locked; - -import java.util.Collection; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.locks.Lock; - -import com.salesfoce.apollo.utils.proto.Clock; -import com.salesfoce.apollo.utils.proto.StampedClock; -import com.salesforce.apollo.crypto.Digest; - -/** - * @author hal.hildebrand - * - */ -public record IntCausalClock(BloomClock clock, AtomicInteger sequenceNumber, Lock lock) - implements CausalClock { - - @Override - public Integer instant() { - return sequenceNumber.get(); - } - - @Override - public int compareTo(double fpr, ClockValue b) { - return locked(() -> clock.compareTo(fpr, b), lock); - } - - @Override - public BloomClockValue toBloomClockValue() { - return locked(() -> clock.toBloomClockValue(), lock); - } - - @Override - public Clock toClock() { - return locked(() -> clock.toClock(), lock); - } - - @Override - public StampedClock toStampedClock() { - return locked(() -> StampedClock.newBuilder().setInt(sequenceNumber.get()).setClock(clock.toClock()).build(), - lock); - } - - @Override - public StampedClockValue observe(Digest digest) { - return locked(() -> { - clock.add(digest); - return new IntStampedClockValue(clock.toBloomClockValue(), sequenceNumber.get()); - }, lock); - } - - @Override - public StampedClockValue merge(StampedClockValue b) { - return locked(() -> { - clock.merge(b); - int sequence = Math.max(sequenceNumber.get(), b.instant()); - sequenceNumber.set(sequence); - return new IntStampedClockValue(clock.toBloomClockValue(), sequence); - }, lock); - } - - @Override - public StampedClock stamp() { - return locked(() -> StampedClock.newBuilder() - .setInt(sequenceNumber.incrementAndGet()) - .setClock(clock.toClock()) - .build(), - lock); - } - - @Override - public StampedClockValue current() { - return locked(() -> new IntStampedClockValue(clock.toBloomClockValue(), sequenceNumber.get()), lock); - } - - @Override - public Integer observeAll(Collection digests) { - return locked(() -> { - clock.addAll(digests); - return instant(); - }, lock); - } - - public void reset() { - locked(() -> { - clock.reset(); - sequenceNumber.set(0); - }, lock); - } - - @Override - public String toString() { - return "ICC[" + current() + "]"; - } - - @Override - public int sum() { - return clock.sum(); - } -} diff --git a/utils/src/main/java/com/salesforce/apollo/causal/IntStampedClockValue.java b/utils/src/main/java/com/salesforce/apollo/causal/IntStampedClockValue.java deleted file mode 100644 index 739e6bcb45..0000000000 --- a/utils/src/main/java/com/salesforce/apollo/causal/IntStampedClockValue.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2021, salesforce.com, inc. - * All rights reserved. - * SPDX-License-Identifier: BSD-3-Clause - * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause - */ -package com.salesforce.apollo.causal; - -import com.salesfoce.apollo.utils.proto.Clock; -import com.salesfoce.apollo.utils.proto.StampedClock; - -/** - * @author hal.hildebrand - * - */ -public record IntStampedClockValue(BloomClockValue clock, int stamp) implements StampedClockValue { - - public static IntStampedClockValue from(StampedClock c) { - return new IntStampedClockValue(ClockValue.of(c.getClock()), c.getInt()); - } - - @Override - public BloomClockValue toBloomClockValue() { - return clock; - } - - public StampedClock toStampedClock() { - return StampedClock.newBuilder().setClock(clock.toClock()).setInt(stamp).build(); - } - - @Override - public int compareTo(double fpr, ClockValue b) { - return clock.compareTo(fpr, b); - } - - @Override - public Clock toClock() { - return clock.toClock(); - } - - @Override - public Integer instant() { - return stamp; - } - - @Override - public String toString() { - return "{" + instant() + ":" + BloomClock.print(clock) + "}"; - } - - @Override - public int sum() { - return clock.sum(); - } -} diff --git a/utils/src/main/java/com/salesforce/apollo/causal/StampedClockValueComparator.java b/utils/src/main/java/com/salesforce/apollo/causal/StampedClockValueComparator.java deleted file mode 100644 index ba0b1a010d..0000000000 --- a/utils/src/main/java/com/salesforce/apollo/causal/StampedClockValueComparator.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2021, salesforce.com, inc. - * All rights reserved. - * SPDX-License-Identifier: BSD-3-Clause - * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause - */ -package com.salesforce.apollo.causal; - -import java.util.Comparator; - -/** - * @author hal.hildebrand - * - */ - -/** - * A comparator for Bloom Clock stamped with monotonically increasing values. - * Because the Bloom Clock is a probabalistic data structure, this comparator - * requires a provided false positive rate (FPR). This FPR applies when - * clock A is compared to clock B and the determination is that A proceeds B - - * this is the equivalent of "contains" in a vanilla Bloom Filter. The - * "proceeds", or "contains" function is probabalistic in that there is still a - * possibility this is a false positive (the past is "contained" in the present - * and future - the past is a "member" of the set of the present, or current - * value of the clock - so the FPR applies to the "proceeded" relationship). - *

- * - */ -public class StampedClockValueComparator> implements Comparator> { - private final double fpr; - - /** - * - * @param fpr - the False Positive Rate. Acceptable probability from 0.0 -> 1.0 - * of a false positive when determining precidence. - */ - public StampedClockValueComparator(double fpr) { - this.fpr = fpr; - } - - /** - * Provides comparison between two Bloom Clock values. If the bloom clock - * comparison is undeciable within the bounds of the FPR, the instance() stamps - * on each clock break the tie. The comparator has a false positive threshold - * that determines the acceptable threshold of assurance that clock A proceeds - * clock B. - *

- * If clock A occurs after clock B, then this function returns 1 - *

- * If clocks A and B are not comparable, i.e. they are "simultaneous", then this - * function returns 0. - *

- * If clock A proceeds B within this comparator's false positive rate, then this - * function returns -1. - */ - @Override - public int compare(StampedClockValue a, StampedClockValue b) { - var comparison = a.compareTo(fpr, b); - if (comparison > 0) { - return 1; - } else if (comparison == 0) { - return a.instant().compareTo(b.instant()); - } - return -1; - } - - @Override - public String toString() { - return "SCVC [fpr=" + fpr + "]"; - } -} diff --git a/utils/src/main/java/com/salesforce/apollo/causal/TimeStampedClockValue.java b/utils/src/main/java/com/salesforce/apollo/causal/TimeStampedClockValue.java deleted file mode 100644 index 1cde6aa7e6..0000000000 --- a/utils/src/main/java/com/salesforce/apollo/causal/TimeStampedClockValue.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2021, salesforce.com, inc. - * All rights reserved. - * SPDX-License-Identifier: BSD-3-Clause - * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause - */ -package com.salesforce.apollo.causal; - -import java.time.Instant; - -import com.google.protobuf.Timestamp; -import com.salesfoce.apollo.utils.proto.Clock; -import com.salesfoce.apollo.utils.proto.StampedClock; - -/** - * @author hal.hildebrand - * - */ -public record TimeStampedClockValue(BloomClockValue clock, Instant stamp) implements StampedClockValue { - - public static TimeStampedClockValue from(StampedClock c) { - Timestamp ts = c.getTimestamp(); - return new TimeStampedClockValue(ClockValue.of(c.getClock()), - Instant.ofEpochSecond(ts.getSeconds(), ts.getNanos())); - } - - @Override - public BloomClockValue toBloomClockValue() { - return clock; - } - - @Override - public StampedClock toStampedClock() { - return StampedClock.newBuilder() - .setClock(clock.toClock()) - .setTimestamp(Timestamp.newBuilder() - .setSeconds(stamp.getEpochSecond()) - .setNanos(stamp.getNano())) - .build(); - } - - @Override - public int compareTo(double fpr, ClockValue b) { - return clock.compareTo(fpr, b); - } - - @Override - public Clock toClock() { - return clock.toClock(); - } - - @Override - public Instant instant() { - return null; - } - - @Override - public int sum() { - return clock.sum(); - } - -} diff --git a/utils/src/main/java/com/salesforce/apollo/utils/Pair.java b/utils/src/main/java/com/salesforce/apollo/utils/Pair.java deleted file mode 100644 index 534b2f3cd3..0000000000 --- a/utils/src/main/java/com/salesforce/apollo/utils/Pair.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2021, salesforce.com, inc. - * All rights reserved. - * SPDX-License-Identifier: BSD-3-Clause - * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause - */ -package com.salesforce.apollo.utils; - -/** - * @author hal.hildebrand - * - */ -public class Pair { - - public static final Pair EMPTY_PAIR = new Pair<>(null, null); - - @SuppressWarnings("unchecked") - public static Pair emptyPair() { - return (Pair) EMPTY_PAIR; - } - - public final A a; - - public final B b; - - public Pair(A a, B b) { - this.a = a; - this.b = b; - } -} diff --git a/utils/src/main/java/com/salesforce/apollo/utils/Utils.java b/utils/src/main/java/com/salesforce/apollo/utils/Utils.java deleted file mode 100644 index ce42c267ea..0000000000 --- a/utils/src/main/java/com/salesforce/apollo/utils/Utils.java +++ /dev/null @@ -1,1079 +0,0 @@ -/** - * (C) Copyright 2009 Hal Hildebrand, All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.salesforce.apollo.utils; - -import com.salesforce.apollo.crypto.Digest; -import com.salesforce.apollo.crypto.DigestAlgorithm; -import com.salesforce.apollo.crypto.SignatureAlgorithm; -import com.salesforce.apollo.crypto.cert.BcX500NameDnImpl; -import com.salesforce.apollo.crypto.cert.CertificateWithPrivateKey; -import com.salesforce.apollo.crypto.cert.Certificates; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.*; -import java.lang.Thread.UncaughtExceptionHandler; -import java.lang.reflect.Field; -import java.net.*; -import java.nio.channels.ClosedChannelException; -import java.security.KeyPair; -import java.security.PublicKey; -import java.security.cert.X509Certificate; -import java.time.Instant; -import java.util.*; -import java.util.Map.Entry; -import java.util.concurrent.Callable; -import java.util.concurrent.locks.Lock; -import java.util.function.Consumer; -import java.util.function.Supplier; -import java.util.zip.*; - -import static com.salesforce.apollo.crypto.QualifiedBase64.qb64; - -/** - * - * @author Hal Hildebrand - * - */ - -public class Utils { - public static Object accessField(String fieldName, Object target) - throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException { - Field field; - try { - field = target.getClass().getDeclaredField(fieldName); - } catch (NoSuchFieldException e) { - Class superClass = target.getClass().getSuperclass(); - if (superClass == null) { - throw e; - } - return accessField(fieldName, target, superClass); - } - field.setAccessible(true); - return field.get(target); - } - - public static Object accessField(String fieldName, Object target, Class targetClass) - throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException { - Field field; - try { - field = targetClass.getDeclaredField(fieldName); - } catch (NoSuchFieldException e) { - Class superClass = targetClass.getSuperclass(); - if (superClass == null) { - throw e; - } - return accessField(fieldName, target, superClass); - } - field.setAccessible(true); - return field.get(target); - } - - public static void addToZip(File root, File file, ZipOutputStream zos) throws IOException { - String relativePath = Utils.relativize(root, file.getAbsoluteFile()).getPath(); - if (file.isDirectory()) { - relativePath += '/'; - } - ZipEntry ze = new ZipEntry(relativePath); - zos.putNextEntry(ze); - if (file.isDirectory()) { - for (File child : file.listFiles()) { - addToZip(root, child, zos); - } - } else { - try (FileInputStream fis = new FileInputStream(file)) { - copy(fis, zos); - } - } - } - - /** - * Find a free port for any local address - * - * @return the port number or -1 if none available - */ - public static int allocatePort() { - return allocatePort(null); - } - - /** - * Find a free port on the interface with the given address - * - * @return the port number or -1 if none available - */ - public static int allocatePort(InetAddress host) { - InetAddress address = host == null ? InetAddress.getLoopbackAddress() : host; - - try (ServerSocket socket = new ServerSocket(0, 0, address);) { - socket.setReuseAddress(true); - var localPort = socket.getLocalPort(); - socket.close(); - return localPort; - } catch (IOException e) { - return -1; - } - } - - /** - * Clean the contents of a directory - * - * @param directory - */ - public static void clean(File directory) { - if (directory.exists()) { - if (directory.isDirectory()) { - for (File file : directory.listFiles()) { - if (file.isDirectory()) { - remove(file); - } else { - if (!file.delete()) { - throw new IllegalStateException(String.format("Cannot delete [%s] ", file)); - } - } - } - } - } - } - - public static void copy(File sourceFile, File destFile) throws IOException { - copy(sourceFile, destFile, 4096); - } - - /** - * Copy the contents of the source file into the destination file using the - * supplied buffer - * - * @param sourceFile - * @param destFile - * @param buffer - * @throws IOException - */ - public static void copy(File sourceFile, File destFile, byte[] buffer) throws IOException { - try (InputStream is = new FileInputStream(sourceFile); OutputStream os = new FileOutputStream(destFile);) { - copy(is, os, buffer); - } - } - - /** - * Copy the contents of the source file into the destination file using a buffer - * of the supplied size - * - * @param sourceFile - * @param destFile - * @param bufferSize - * @throws IOException - */ - public static void copy(File sourceFile, File destFile, int bufferSize) throws IOException { - copy(sourceFile, destFile, new byte[bufferSize]); - } - - /** - * - * Copy and transform the zip entry to the destination. If the transformation - * extensions contains the entry's extension, then ${xxx} style parameters are - * replace with the supplied properties or System.getProperties() - * - * @param dest - * @param zf - * @param ze - * @param extensions - * @param properties - * @throws IOException - */ - public static void copy(File dest, ZipFile zf, ZipEntry ze, Map properties, - Collection extensions) throws IOException { - try (InputStream is = zf.getInputStream(ze)) { - File outFile = new File(dest, ze.getName()); - if (ze.isDirectory()) { - outFile.mkdirs(); - } else { - File parent = outFile.getParentFile(); - if (parent != null) { - parent.mkdirs(); - } - - try (FileOutputStream fos = new FileOutputStream(outFile)) { - if (extensions.contains(getExtension(outFile.getName()))) { - replaceProperties(is, fos, properties); - } else { - copy(is, fos); - } - } - } - } - } - - /** - * Copy the contents of the input stream into the output stream using the - * default buffer size - * - * @param is - * @param os - * @throws IOException - */ - public static void copy(InputStream is, OutputStream os) throws IOException { - copy(is, os, 16 * 1024); - } - - /** - * Copy the contents of the input stream to the output stream. It is the - * caller's responsibility to close the streams. - * - * @param is - source - * @param os - destination - * @param buffer - byte buffer to use - * @throws IOException - */ - public static void copy(InputStream is, OutputStream os, byte[] buffer) throws IOException { - int len; - while ((len = is.read(buffer)) > 0) { - os.write(buffer, 0, len); - } - } - - /** - * Copy the contents of the input stream to the output stream. It is the - * caller's responsibility to close the streams. - * - * @param is - source - * @param os - destination - * @param bufferSize - buffer size to use - * @throws IOException - */ - public static void copy(InputStream is, OutputStream os, int bufferSize) throws IOException { - copy(is, os, new byte[bufferSize]); - } - - /** - * Replicate the entire contents of the source directory to the target directory - * - * @param sourceLocation - must be a directory and must exist - * @param targetLocation - if exists, must be a directory. Will be created with - * full paths if does not exist - * @throws IOException - */ - public static void copyDirectory(File sourceLocation, File targetLocation) throws IOException { - - if (sourceLocation.isDirectory()) { - if (!targetLocation.exists()) { - if (!targetLocation.mkdirs()) { - throw new IllegalArgumentException( - String.format("Cannot create directory [%s]", targetLocation.getAbsolutePath())); - } - } else if (targetLocation.isFile()) { - throw new IllegalArgumentException( - String.format("Target location must be a directory [%s]", targetLocation.getAbsolutePath())); - } - - String[] children = sourceLocation.list(); - for (String element : children) { - File child = new File(sourceLocation, element); - File targetChild = new File(targetLocation, element); - if (child.isDirectory()) { - copyDirectory(child, targetChild); - } else { - copy(child, targetChild); - } - } - } else { - throw new IllegalArgumentException( - String.format("[%s] is not a directory", sourceLocation.getAbsolutePath())); - } - } - - /** - * Create a zip from the contents of a directory. - * - * @param root - the root of the zip contents - * @param os - the output stream to create the zip with - * @throws IOException - if anything goes wrong - */ - public static void createZip(File root, boolean includeRoot, OutputStream os) throws IOException { - if (!root.isDirectory()) { - throw new IllegalArgumentException(String.format("%s is not a directory", root)); - } - File directory = root.getAbsoluteFile(); - - ZipOutputStream zos = new ZipOutputStream(os); - if (includeRoot) { - String rootPath = root.getName(); - if (!rootPath.endsWith("/")) { - rootPath += '/'; - } - ZipEntry ze = new ZipEntry(rootPath); - zos.putNextEntry(ze); - directory = directory.getParentFile(); - } - for (File file : root.listFiles()) { - addToZip(directory, file, zos); - } - zos.finish(); - zos.flush(); - } - - public static BcX500NameDnImpl encode(Digest digest, String host, int port, PublicKey signingKey) { - return new BcX500NameDnImpl( - String.format("CN=%s, L=%s, UID=%s, DC=%s", host, port, qb64(digest), qb64(signingKey))); - } - - /** - * Expand the zip resource into the destination, replacing any ${propName} style - * properties with the corresponding values in the substitutions map - * - * @param zip - the zip file to expand - * @param extensions - the list of file extensions targeted for property - * substitution - * @param substitutions - the map of substitutions - * @param destination - the destination directory for the expansion - * - * @throws IOException - * @throws ZipException - */ - public static void expandAndReplace(File zip, File dest, Map substitutions, - Collection extensions) throws ZipException, IOException { - try (InputStream is = new FileInputStream(zip)) { - expandAndReplace(is, dest, substitutions, extensions); - } - } - - /** - * - * Copy and transform the zip entry to the destination. If the transformation - * extensions contains the entry's extension, then ${xxx} style parameters are - * replace with the supplied properties or System.getProperties() - * - * @param dest - * @param zis - * @param ze - * @param extensions - * @param properties - * @throws IOException - */ - public static void expandAndReplace(File dest, ZipInputStream zis, ZipEntry ze, Map properties, - Collection extensions) throws IOException { - File outFile = new File(dest, ze.getName()); - if (ze.isDirectory()) { - outFile.mkdirs(); - } else { - transform(properties, extensions, zis, outFile); - } - } - - /** - * Expand the zip resource into the destination, replacing any ${propName} style - * properties with the corresponding values in the substitutions map - * - * @param is - the zip input stream to expand - * @param extensions - the list of file extensions targeted for property - * substitution - * @param substitutions - the map of substitutions - * @param destination - the destination directory for the expansion - * - * @throws IOException - * @throws ZipException - */ - public static void expandAndReplace(InputStream is, File dest, Map substitutions, - Collection extensions) throws ZipException, IOException { - if (!dest.exists() && !dest.mkdir()) { - throw new IOException(String.format("Cannot create destination directory: %s", dest.getAbsolutePath())); - } - ZipInputStream zis = new ZipInputStream(is); - ZipEntry ze = zis.getNextEntry(); - while (ze != null) { - expandAndReplace(dest, zis, ze, substitutions, extensions); - ze = zis.getNextEntry(); - } - } - - /** - * Provision the configured process directory from the zip resource - * - * @param zip - * @param extensions - * @param map - * @param destination - * - * @throws IOException - * @throws ZipException - */ - public static void explode(File zip, File dest, Map map, Collection extensions) - throws ZipException, IOException { - expandAndReplace(zip, dest, map, extensions); - } - - /** - * Find the substitution value for the key in the properties. If the supplied - * properties are null, use the system properties. - * - * @param key - * @param props - * @return - */ - public static String findValue(final String key, final Map props) { - String value; - // check from the properties - if (props != null) { - value = props.get(key.toString()); - } else { - value = System.getProperty(key); - } - if (value == null) { - // Check for a default value ${key:default} - int colon = key.indexOf(':'); - if (colon > 0) { - String realKey = key.substring(0, colon); - if (props != null) { - value = props.get(realKey); - } else { - value = System.getProperty(realKey); - } - - if (value == null) { - // Check for a composite key, "key1,key2" - value = resolveCompositeKey(realKey, props); - - // Not a composite key either, use the specified default - if (value == null) { - value = key.substring(colon + 1); - } - } - } else { - // No default, check for a composite key, "key1,key2" - value = resolveCompositeKey(key, props); - } - } - return value; - } - - public static InetAddress getAddress(NetworkInterface iface) { - return getAddress(iface, true); - } - - public static InetAddress getAddress(NetworkInterface iface, boolean requireIPV4) { - InetAddress interfaceAddress = null; - for (InterfaceAddress address : iface.getInterfaceAddresses()) { - if (requireIPV4) { - if (address.getAddress().getAddress().length == 4) { - interfaceAddress = address.getAddress(); - break; - } - } else { - interfaceAddress = address.getAddress(); - } - } - if (interfaceAddress == null) { - throw new IllegalStateException( - String.format("Unable ot determine bound %s address for interface '%s'", requireIPV4 ? "IPV4" : "IPV4/6", - iface)); - } - return interfaceAddress; - } - - /** - * Answer the byte array containing the contents of the file - * - * @param file - * @return - * @throws IOException - */ - public static byte[] getBits(File file) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - InputStream fis = new FileInputStream(file); - copy(fis, baos); - return baos.toByteArray(); - } - - /** - * Answer the string representation of the document - * - * @param openStream - ye olde stream - * @return the string the stream represents - * @throws IOException - if we're boned - */ - public static String getDocument(InputStream is) throws IOException { - return getDocument(is, new HashMap()); - } - - /** - * Answer the string representation of the document - * - * @param openStream - ye olde stream - * @param - the replacement properties for the document - * @return the string the stream represents - * @throws IOException - if we're boned - */ - public static String getDocument(InputStream is, Map properties) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - replaceProperties(is, baos, properties); - return baos.toString(); - } - - /** - * Answer the string representation of the document - * - * @param openStream - ye olde stream - * @param - the replacement properties for the document - * @return the string the stream represents - * @throws IOException - if we're boned - */ - public static String getDocument(InputStream is, Properties properties) throws IOException { - Map props = transform(properties); - return getDocument(is, props); - } - - /** - * Answer the extension of the file - * - * @param file - * @return - */ - public static String getExtension(File file) { - String name = file.getName(); - int index = name.lastIndexOf('.'); - if (index == -1) { - return ""; - } - return name.substring(index + 1); - } - - /** - * Answer the extension of the file - * - * @param file - * @return - */ - public static String getExtension(String file) { - int index = file.lastIndexOf('.'); - if (index == -1) { - return ""; - } - return file.substring(index + 1); - } - - public static NetworkInterface getInterface(String ifaceName) throws SocketException { - if (ifaceName == null) { - NetworkInterface iface = NetworkInterface.getByIndex(1); - if (iface == null) { - throw new IllegalArgumentException( - "Supplied ANY address for endpoint: %s with no networkInterface defined, cannot find network interface 1 "); - } - return iface; - } else { - NetworkInterface iface = NetworkInterface.getByName(ifaceName); - if (iface == null) { - throw new IllegalArgumentException(String.format("Cannot find network interface: %s ", ifaceName)); - } - return iface; - } - } - - public static CertificateWithPrivateKey getMember(Digest id) { - KeyPair keyPair = SignatureAlgorithm.ED_25519.generateKeyPair(); - var notBefore = Instant.now(); - var notAfter = Instant.now().plusSeconds(10_000); - String localhost = InetAddress.getLoopbackAddress().getHostName(); - X509Certificate generated = Certificates.selfSign(false, - encode(id, localhost, allocatePort(), keyPair.getPublic()), - keyPair, notBefore, notAfter, Collections.emptyList()); - return new CertificateWithPrivateKey(generated, keyPair.getPrivate()); - } - - public static CertificateWithPrivateKey getMember(int index) { - byte[] hash = new byte[32]; - hash[0] = (byte) index; - return getMember(new Digest(DigestAlgorithm.DEFAULT, hash)); - } - - /** - * Answer the extension of the file - * - * @param file - * @return - */ - public static String getNameWithoutExtension(File file) { - String name = file.getName(); - int index = name.lastIndexOf('.'); - if (index == -1) { - return ""; - } - return name.substring(0, index); - } - - /** - * Answer a property map read from the stream - * - * @param is - the stream containing the property map - * @return the Map of properties - * @throws IOException - */ - public static Map getProperties(InputStream is) throws IOException { - Map properties = new HashMap<>(); - Properties props = new Properties(); - props.load(is); - for (Entry entry : props.entrySet()) { - properties.put((String) entry.getKey(), (String) entry.getValue()); - } - return properties; - } - - /** - * Answer the string representation of the inputstream - * - * @param openStream - ye olde stream - * @return the string the stream represents - * @throws IOException - if we're boned - */ - public static String getString(InputStream is) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - copy(is, baos); - return baos.toString(); - } - - /** - * Remove and reinitialze the directory. The directory and full paths will be - * created if it does not exist - * - * @param directory - */ - public static void initializeDirectory(File directory) { - clean(directory); - if (!directory.exists() && !directory.mkdirs()) { - throw new IllegalStateException("Cannot create directory: " + directory); - } - } - - /** - * Remove and reinitialze the directory. The directory and full paths will be - * created if it does not exist - * - * @param dir - */ - public static void initializeDirectory(String dir) { - initializeDirectory(new File(dir)); - } - - /** - * Answer true if the io exception is a form of a closed connection - * - * @param ioe - * @return - */ - public static boolean isClosedConnection(IOException ioe) { - return ioe instanceof ClosedChannelException || "Broken pipe".equals(ioe.getMessage()) - || "Connection reset by peer".equals(ioe.getMessage()); - } - - public static T locked(Callable call, final Lock lock) { - lock.lock(); - try { - return call.call(); - } catch (Exception e) { - throw new IllegalStateException(e); - } finally { - lock.unlock(); - } - } - - public static void locked(Runnable call, final Lock lock) { - lock.lock(); - try { - call.run(); - } finally { - lock.unlock(); - } - } - - public static File relativize(File parent, File child) { - URI base = parent.toURI(); - URI absolute = child.toURI(); - URI relative = base.relativize(absolute); - return new File(relative.getPath()); - } - - /** - * Remove the file. If the file is a directory, the entire contents will be - * recursively removed. - * - * @param directoryOrFile - */ - public static void remove(File directoryOrFile) { - if (directoryOrFile.exists()) { - if (directoryOrFile.isDirectory()) { - for (File file : directoryOrFile.listFiles()) { - if (file.isDirectory()) { - remove(file); - } else { - if (!file.delete()) { - throw new IllegalStateException(String.format("Cannot delete [%s] ", file)); - } - } - } - } - if (!directoryOrFile.delete()) { - throw new IllegalStateException(String.format("Cannot delete [%s] ", directoryOrFile)); - } - } - } - - /** - * Go through the input stream and replace any occurance of ${p} with the - * props.get(p) value. If there is no such property p defined, then the ${p} - * reference will remain unchanged. - * - * If the property reference is of the form ${p:v} and there is no such property - * p, then the default value v will be returned. - * - * If the property reference is of the form ${p1,p2} or ${p1,p2:v} then the - * primary and the secondary properties will be tried in turn, before returning - * either the unchanged input, or the default value. - * - * @param in - the file with possible ${x} references - * @param out - the file output for the transformed input - * @param props - the source for ${x} property ref values, null means use - * System.getProperty() - * @throws IOException - */ - public static void replaceProperties(File in, File out, Map props) throws IOException { - try (InputStream is = new FileInputStream(in); OutputStream os = new FileOutputStream(out);) { - - replaceProperties(is, os, props); - } - } - - /** - * Go through the input stream and replace any occurance of ${p} with the - * props.get(p) value. If there is no such property p defined, then the ${p} - * reference will remain unchanged. - * - * If the property reference is of the form ${p:v} and there is no such property - * p, then the default value v will be returned. - * - * If the property reference is of the form ${p1,p2} or ${p1,p2:v} then the - * primary and the secondary properties will be tried in turn, before returning - * either the unchanged input, or the default value. - * - * @param in - the stream with possible ${x} references - * @param out - the output for the transformed input - * @param props - the source for ${x} property ref values, null means use - * System.getProperty() - */ - public static void replaceProperties(final InputStream in, final OutputStream out, final Map props) - throws IOException { - Reader reader = new BufferedReader(new InputStreamReader(in)); - Writer writer = new BufferedWriter(new OutputStreamWriter(out)); - ParsingState state = ParsingState.PASS_THROUGH; - - StringBuffer keyBuffer = null; - for (int next = reader.read(); next != -1; next = reader.read()) { - char c = (char) next; - switch (state) { - case PASS_THROUGH: { - if (c == '$') { - state = ParsingState.DOLLAR; - } else { - writer.append(c); - } - break; - } - case DOLLAR: { - if (c == '{') { - state = ParsingState.BRACKET; - keyBuffer = new StringBuffer(); - } else if (c == '$') { - writer.append('$'); // just saw $$ - } else { - state = ParsingState.PASS_THROUGH; - writer.append('$'); - writer.append(c); - } - break; - } - case BRACKET: { - if (c == '}') { - state = ParsingState.PASS_THROUGH; - if (keyBuffer.length() == 0) { - writer.append("${}"); - } else { - String value = null; - String key = keyBuffer.toString(); - value = findValue(key, props); - - if (value != null) { - writer.append(value); - } else { - writer.append("${"); - writer.append(key); - writer.append('}'); - } - } - keyBuffer = null; - } else if (c == '$') { - // We're inside of a ${ already, so bail and reset - state = ParsingState.DOLLAR; - writer.append("${"); - writer.append(keyBuffer.toString()); - keyBuffer = null; - } else { - keyBuffer.append(c); - } - } - } - } - writer.flush(); - } - - /** - * Try to resolve a "key" from the provided properties by checking if it is - * actually a "key1,key2", in which case try first "key1", then "key2". If all - * fails, return null. - * - * It also accepts "key1," and ",key2". - * - * @param key the key to resolve - * @param props the properties to use - * @return the resolved key or null - */ - public static String resolveCompositeKey(final String key, Map props) { - String value = null; - - // Look for the comma - int comma = key.indexOf(','); - if (comma > -1) { - // If we have a first part, try resolve it - if (comma > 0) { - // Check the first part - String key1 = key.substring(0, comma); - if (props != null) { - value = props.get(key1); - } else { - value = System.getProperty(key1); - } - } - // Check the second part, if there is one and first lookup failed - if (value == null && comma < key.length() - 1) { - String key2 = key.substring(comma + 1); - if (props != null) { - value = props.get(key2); - } else { - value = System.getProperty(key2); - } - } - } - // Return whatever we've found or null - return value; - } - - /** - * Resolve a resource. First see if the supplied resource is an URL. If so, open - * it and return the stream. If not, try for a file. If that exists and is not a - * directory, then return that stream. Finally, look for a classpath resource, - * relative to the supplied base class. If that exists, open the stream and - * return that. Otherwise, barf - * - * @param base - the base class for resolving classpath resources - may be - * null - * @param resource - the resource to resolve - * @return the InputStream of the resolved resource - * @throws IOException - if something gnarly happens, or we can't find your - * resource - */ - public static InputStream resolveResource(Class base, String resource) throws IOException { - return resolveResourceURL(base, resource).openStream(); - } - - /** - * Resolve a resource. Replace any ${foo} style properties in the resource with - * the supplied properties map. First see if the supplied resource is an URL. If - * so, open it and return the stream. If not, try for a file. If that exists and - * is not a directory, then return that stream. Finally, look for a classpath - * resource, relative to the supplied base class. If that exists, open the - * stream and return that. Otherwise, barf - * - * @param base - the base class for resolving classpath resources - may be - * null - * @param resource - the resource to resolve - * @param properties - the properties to replace in the resource stream - * @return the InputStream of the resolved resource - * @throws IOException - if something gnarly happens, or we can't find your - * resource - */ - public static InputStream resolveResource(Class base, String resource, Map properties) - throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - replaceProperties(resolveResource(base, resource), baos, properties); - return new ByteArrayInputStream(baos.toByteArray()); - } - - /** - * Resolve a resource. Replace any ${foo} style properties in the resource with - * the supplied properties map. First see if the supplied resource is an URL. If - * so, open it and return the stream. If not, try for a file. If that exists and - * is not a directory, then return that stream. Finally, look for a classpath - * resource, relative to the supplied base class. If that exists, open the - * stream and return that. Otherwise, barf - * - * @param base - the base class for resolving classpath resources - may be - * null - * @param resource - the resource to resolve - * @param properties - the properties to replace in the resource stream - * @return the InputStream of the resolved resource - * @throws IOException - if something gnarly happens, or we can't find your - * resource - */ - public static InputStream resolveResource(Class base, String resource, Properties properties) - throws IOException { - return resolveResource(base, resource, transform(properties)); - } - - /** - * Resolve a resource. First see if the supplied resource is an URL. If so, open - * it and return the stream. If not, try for a file. If that exists and is not a - * directory, then return that stream. Finally, look for a classpath resource, - * relative to the supplied base class. If that exists, open the stream and - * return that. Otherwise, barf - * - * @param base - the base class for resolving classpath resources - may be - * null - * @param resource - the resource to resolve - * @return the URL of the resolved resource - * @throws IOException - if something gnarly happens, or we can't find your - * resource - */ - public static URL resolveResourceURL(Class base, String resource) throws IOException { - try { - URL url = new URI(resource).toURL(); - return url; - } catch (MalformedURLException e) { - LoggerFactory.getLogger(Utils.class) - .trace( - String.format("The resource is not a valid URL: %s\n Trying to find a corresponding file", - resource)); - } catch (URISyntaxException e) { - LoggerFactory.getLogger(Utils.class) - .trace( - String.format("The resource is not a valid URL: %s\n Trying to find a corresponding file", - resource)); - } - File configFile = new File(resource); - if (!configFile.exists()) { - if (base == null) { - throw new FileNotFoundException(String.format("resource does not exist as a file: %s", resource)); - } - } else if (configFile.isDirectory()) { - LoggerFactory.getLogger(Utils.class) - .trace(String.format("resource is a directory: %s\n Trying to find corresponding resource", - resource)); - } else { - return configFile.toURI().toURL(); - } - return base.getResource(resource); - } - - /** - * Transform the contents of the input stream, replacing any ${p} values in the - * stream with the value in the supplied properties. The transformed contents - * are placed in the supplied output file. - * - * @param properties - * @param extensions - * @param is - * @param outFile - * @throws FileNotFoundException - * @throws IOException - */ - public static void transform(Map properties, Collection extensions, InputStream is, - File outFile) throws FileNotFoundException, IOException { - File parent = outFile.getParentFile(); - if (parent != null) { - parent.mkdirs(); - } - - try (FileOutputStream fos = new FileOutputStream(outFile);) { - if (extensions.contains(getExtension(outFile.getName()))) { - replaceProperties(is, fos, properties); - } else { - copy(is, fos); - } - } - } - - public static Map transform(Properties properties) { - Map props = new HashMap<>(); - for (Map.Entry entry : properties.entrySet()) { - props.put((String) entry.getKey(), (String) entry.getValue()); - } - return props; - } - - public static UncaughtExceptionHandler uncaughtHandler(Logger log) { - return (thread, throwable) -> { - log.error("Uncaught exception on thread: {}", thread.getName(), throwable); - }; - } - - public static boolean waitForCondition(int maxWaitTime, final int sleepTime, Supplier condition) { - long endTime = System.currentTimeMillis() + maxWaitTime; - while (System.currentTimeMillis() <= endTime) { - if (condition.get()) { - return true; - } - try { - Thread.sleep(sleepTime); - } catch (InterruptedException e) { - return false; - } - } - return false; - } - - public static boolean waitForCondition(int maxWaitTime, Supplier condition) { - return waitForCondition(maxWaitTime, 100, condition); - } - - public static Callable wrapped(Callable c, Logger log) { - return () -> { - try { - return c.call(); - } catch (Exception e) { - log.error("Error in call", e); - throw new IllegalStateException(e); - } - }; - } - - public static Consumer wrapped(Consumer c, Logger log) { - return t -> { - try { - c.accept(t); - } catch (Exception e) { - log.error("Error in call", e); - throw new IllegalStateException(e); - } - }; - } - - public static Runnable wrapped(Runnable r, Logger log) { - return () -> { - try { - r.run(); - } catch (Throwable e) { - log.error("Error in execution", e); - throw new IllegalStateException(e); - } - }; - } - - private static enum ParsingState { - BRACKET, DOLLAR, PASS_THROUGH - } -} diff --git a/utils/src/test/resources/blake3.license b/utils/src/test/resources/blake3.license deleted file mode 100644 index fe271dfcff..0000000000 --- a/utils/src/test/resources/blake3.license +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2020 Lily Lin - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file diff --git a/utils/src/test/resources/test_vectors.json b/utils/src/test/resources/test_vectors.json deleted file mode 100644 index bf0c565eb4..0000000000 --- a/utils/src/test/resources/test_vectors.json +++ /dev/null @@ -1,138 +0,0 @@ -{ - "_comment": "Each test is an input length and three outputs, one for each of the hash, keyed_hash, and derive_key modes. The input in each case is filled with a 251-byte-long repeating pattern: 0, 1, 2, ..., 249, 250, 0, 1, ... The key used with keyed_hash is the 32-byte ASCII string given in the 'key' field below. For derive_key, the test input is used as the input key, and the context string is 'BLAKE3 2019-12-27 16:29:52 test vectors context'. (As good practice for following the security requirements of derive_key, test runners should make that context string a hardcoded constant, and we do not provided it in machine-readable form.) Outputs are encoded as hexadecimal. Each case is an extended output, and implementations should also check that the first 32 bytes match their default-length output.", - "key": "whats the Elvish word for friend", - "cases": [ - { - "input_len": 0, - "hash": "af1349b9f5f9a1a6a0404dea36dcc9499bcb25c9adc112b7cc9a93cae41f3262e00f03e7b69af26b7faaf09fcd333050338ddfe085b8cc869ca98b206c08243a26f5487789e8f660afe6c99ef9e0c52b92e7393024a80459cf91f476f9ffdbda7001c22e159b402631f277ca96f2defdf1078282314e763699a31c5363165421cce14d", - "keyed_hash": "92b2b75604ed3c761f9d6f62392c8a9227ad0ea3f09573e783f1498a4ed60d26b18171a2f22a4b94822c701f107153dba24918c4bae4d2945c20ece13387627d3b73cbf97b797d5e59948c7ef788f54372df45e45e4293c7dc18c1d41144a9758be58960856be1eabbe22c2653190de560ca3b2ac4aa692a9210694254c371e851bc8f", - "derive_key": "2cc39783c223154fea8dfb7c1b1660f2ac2dcbd1c1de8277b0b0dd39b7e50d7d905630c8be290dfcf3e6842f13bddd573c098c3f17361f1f206b8cad9d088aa4a3f746752c6b0ce6a83b0da81d59649257cdf8eb3e9f7d4998e41021fac119deefb896224ac99f860011f73609e6e0e4540f93b273e56547dfd3aa1a035ba6689d89a0" - }, - { - "input_len": 1, - "hash": "2d3adedff11b61f14c886e35afa036736dcd87a74d27b5c1510225d0f592e213c3a6cb8bf623e20cdb535f8d1a5ffb86342d9c0b64aca3bce1d31f60adfa137b358ad4d79f97b47c3d5e79f179df87a3b9776ef8325f8329886ba42f07fb138bb502f4081cbcec3195c5871e6c23e2cc97d3c69a613eba131e5f1351f3f1da786545e5", - "keyed_hash": "6d7878dfff2f485635d39013278ae14f1454b8c0a3a2d34bc1ab38228a80c95b6568c0490609413006fbd428eb3fd14e7756d90f73a4725fad147f7bf70fd61c4e0cf7074885e92b0e3f125978b4154986d4fb202a3f331a3fb6cf349a3a70e49990f98fe4289761c8602c4e6ab1138d31d3b62218078b2f3ba9a88e1d08d0dd4cea11", - "derive_key": "b3e2e340a117a499c6cf2398a19ee0d29cca2bb7404c73063382693bf66cb06c5827b91bf889b6b97c5477f535361caefca0b5d8c4746441c57617111933158950670f9aa8a05d791daae10ac683cbef8faf897c84e6114a59d2173c3f417023a35d6983f2c7dfa57e7fc559ad751dbfb9ffab39c2ef8c4aafebc9ae973a64f0c76551" - }, - { - "input_len": 1023, - "hash": "10108970eeda3eb932baac1428c7a2163b0e924c9a9e25b35bba72b28f70bd11a182d27a591b05592b15607500e1e8dd56bc6c7fc063715b7a1d737df5bad3339c56778957d870eb9717b57ea3d9fb68d1b55127bba6a906a4a24bbd5acb2d123a37b28f9e9a81bbaae360d58f85e5fc9d75f7c370a0cc09b6522d9c8d822f2f28f485", - "keyed_hash": "c951ecdf03288d0fcc96ee3413563d8a6d3589547f2c2fb36d9786470f1b9d6e890316d2e6d8b8c25b0a5b2180f94fb1a158ef508c3cde45e2966bd796a696d3e13efd86259d756387d9becf5c8bf1ce2192b87025152907b6d8cc33d17826d8b7b9bc97e38c3c85108ef09f013e01c229c20a83d9e8efac5b37470da28575fd755a10", - "derive_key": "74a16c1c3d44368a86e1ca6df64be6a2f64cce8f09220787450722d85725dea59c413264404661e9e4d955409dfe4ad3aa487871bcd454ed12abfe2c2b1eb7757588cf6cb18d2eccad49e018c0d0fec323bec82bf1644c6325717d13ea712e6840d3e6e730d35553f59eff5377a9c350bcc1556694b924b858f329c44ee64b884ef00d" - }, - { - "input_len": 1024, - "hash": "42214739f095a406f3fc83deb889744ac00df831c10daa55189b5d121c855af71cf8107265ecdaf8505b95d8fcec83a98a6a96ea5109d2c179c47a387ffbb404756f6eeae7883b446b70ebb144527c2075ab8ab204c0086bb22b7c93d465efc57f8d917f0b385c6df265e77003b85102967486ed57db5c5ca170ba441427ed9afa684e", - "keyed_hash": "75c46f6f3d9eb4f55ecaaee480db732e6c2105546f1e675003687c31719c7ba4a78bc838c72852d4f49c864acb7adafe2478e824afe51c8919d06168414c265f298a8094b1ad813a9b8614acabac321f24ce61c5a5346eb519520d38ecc43e89b5000236df0597243e4d2493fd626730e2ba17ac4d8824d09d1a4a8f57b8227778e2de", - "derive_key": "7356cd7720d5b66b6d0697eb3177d9f8d73a4a5c5e968896eb6a6896843027066c23b601d3ddfb391e90d5c8eccdef4ae2a264bce9e612ba15e2bc9d654af1481b2e75dbabe615974f1070bba84d56853265a34330b4766f8e75edd1f4a1650476c10802f22b64bd3919d246ba20a17558bc51c199efdec67e80a227251808d8ce5bad" - }, - { - "input_len": 1025, - "hash": "d00278ae47eb27b34faecf67b4fe263f82d5412916c1ffd97c8cb7fb814b8444f4c4a22b4b399155358a994e52bf255de60035742ec71bd08ac275a1b51cc6bfe332b0ef84b409108cda080e6269ed4b3e2c3f7d722aa4cdc98d16deb554e5627be8f955c98e1d5f9565a9194cad0c4285f93700062d9595adb992ae68ff12800ab67a", - "keyed_hash": "357dc55de0c7e382c900fd6e320acc04146be01db6a8ce7210b7189bd664ea69362396b77fdc0d2634a552970843722066c3c15902ae5097e00ff53f1e116f1cd5352720113a837ab2452cafbde4d54085d9cf5d21ca613071551b25d52e69d6c81123872b6f19cd3bc1333edf0c52b94de23ba772cf82636cff4542540a7738d5b930", - "derive_key": "effaa245f065fbf82ac186839a249707c3bddf6d3fdda22d1b95a3c970379bcb5d31013a167509e9066273ab6e2123bc835b408b067d88f96addb550d96b6852dad38e320b9d940f86db74d398c770f462118b35d2724efa13da97194491d96dd37c3c09cbef665953f2ee85ec83d88b88d11547a6f911c8217cca46defa2751e7f3ad" - }, - { - "input_len": 2048, - "hash": "e776b6028c7cd22a4d0ba182a8bf62205d2ef576467e838ed6f2529b85fba24a9a60bf80001410ec9eea6698cd537939fad4749edd484cb541aced55cd9bf54764d063f23f6f1e32e12958ba5cfeb1bf618ad094266d4fc3c968c2088f677454c288c67ba0dba337b9d91c7e1ba586dc9a5bc2d5e90c14f53a8863ac75655461cea8f9", - "keyed_hash": "879cf1fa2ea0e79126cb1063617a05b6ad9d0b696d0d757cf053439f60a99dd10173b961cd574288194b23ece278c330fbb8585485e74967f31352a8183aa782b2b22f26cdcadb61eed1a5bc144b8198fbb0c13abbf8e3192c145d0a5c21633b0ef86054f42809df823389ee40811a5910dcbd1018af31c3b43aa55201ed4edaac74fe", - "derive_key": "7b2945cb4fef70885cc5d78a87bf6f6207dd901ff239201351ffac04e1088a23e2c11a1ebffcea4d80447867b61badb1383d842d4e79645d48dd82ccba290769caa7af8eaa1bd78a2a5e6e94fbdab78d9c7b74e894879f6a515257ccf6f95056f4e25390f24f6b35ffbb74b766202569b1d797f2d4bd9d17524c720107f985f4ddc583" - }, - { - "input_len": 2049, - "hash": "5f4d72f40d7a5f82b15ca2b2e44b1de3c2ef86c426c95c1af0b687952256303096de31d71d74103403822a2e0bc1eb193e7aecc9643a76b7bbc0c9f9c52e8783aae98764ca468962b5c2ec92f0c74eb5448d519713e09413719431c802f948dd5d90425a4ecdadece9eb178d80f26efccae630734dff63340285adec2aed3b51073ad3", - "keyed_hash": "9f29700902f7c86e514ddc4df1e3049f258b2472b6dd5267f61bf13983b78dd5f9a88abfefdfa1e00b418971f2b39c64ca621e8eb37fceac57fd0c8fc8e117d43b81447be22d5d8186f8f5919ba6bcc6846bd7d50726c06d245672c2ad4f61702c646499ee1173daa061ffe15bf45a631e2946d616a4c345822f1151284712f76b2b0e", - "derive_key": "2ea477c5515cc3dd606512ee72bb3e0e758cfae7232826f35fb98ca1bcbdf27316d8e9e79081a80b046b60f6a263616f33ca464bd78d79fa18200d06c7fc9bffd808cc4755277a7d5e09da0f29ed150f6537ea9bed946227ff184cc66a72a5f8c1e4bd8b04e81cf40fe6dc4427ad5678311a61f4ffc39d195589bdbc670f63ae70f4b6" - }, - { - "input_len": 3072, - "hash": "b98cb0ff3623be03326b373de6b9095218513e64f1ee2edd2525c7ad1e5cffd29a3f6b0b978d6608335c09dc94ccf682f9951cdfc501bfe47b9c9189a6fc7b404d120258506341a6d802857322fbd20d3e5dae05b95c88793fa83db1cb08e7d8008d1599b6209d78336e24839724c191b2a52a80448306e0daa84a3fdb566661a37e11", - "keyed_hash": "044a0e7b172a312dc02a4c9a818c036ffa2776368d7f528268d2e6b5df19177022f302d0529e4174cc507c463671217975e81dab02b8fdeb0d7ccc7568dd22574c783a76be215441b32e91b9a904be8ea81f7a0afd14bad8ee7c8efc305ace5d3dd61b996febe8da4f56ca0919359a7533216e2999fc87ff7d8f176fbecb3d6f34278b", - "derive_key": "050df97f8c2ead654d9bb3ab8c9178edcd902a32f8495949feadcc1e0480c46b3604131bbd6e3ba573b6dd682fa0a63e5b165d39fc43a625d00207607a2bfeb65ff1d29292152e26b298868e3b87be95d6458f6f2ce6118437b632415abe6ad522874bcd79e4030a5e7bad2efa90a7a7c67e93f0a18fb28369d0a9329ab5c24134ccb0" - }, - { - "input_len": 3073, - "hash": "7124b49501012f81cc7f11ca069ec9226cecb8a2c850cfe644e327d22d3e1cd39a27ae3b79d68d89da9bf25bc27139ae65a324918a5f9b7828181e52cf373c84f35b639b7fccbb985b6f2fa56aea0c18f531203497b8bbd3a07ceb5926f1cab74d14bd66486d9a91eba99059a98bd1cd25876b2af5a76c3e9eed554ed72ea952b603bf", - "keyed_hash": "68dede9bef00ba89e43f31a6825f4cf433389fedae75c04ee9f0cf16a427c95a96d6da3fe985054d3478865be9a092250839a697bbda74e279e8a9e69f0025e4cfddd6cfb434b1cd9543aaf97c635d1b451a4386041e4bb100f5e45407cbbc24fa53ea2de3536ccb329e4eb9466ec37093a42cf62b82903c696a93a50b702c80f3c3c5", - "derive_key": "72613c9ec9ff7e40f8f5c173784c532ad852e827dba2bf85b2ab4b76f7079081576288e552647a9d86481c2cae75c2dd4e7c5195fb9ada1ef50e9c5098c249d743929191441301c69e1f48505a4305ec1778450ee48b8e69dc23a25960fe33070ea549119599760a8a2d28aeca06b8c5e9ba58bc19e11fe57b6ee98aa44b2a8e6b14a5" - }, - { - "input_len": 4096, - "hash": "015094013f57a5277b59d8475c0501042c0b642e531b0a1c8f58d2163229e9690289e9409ddb1b99768eafe1623da896faf7e1114bebeadc1be30829b6f8af707d85c298f4f0ff4d9438aef948335612ae921e76d411c3a9111df62d27eaf871959ae0062b5492a0feb98ef3ed4af277f5395172dbe5c311918ea0074ce0036454f620", - "keyed_hash": "befc660aea2f1718884cd8deb9902811d332f4fc4a38cf7c7300d597a081bfc0bbb64a36edb564e01e4b4aaf3b060092a6b838bea44afebd2deb8298fa562b7b597c757b9df4c911c3ca462e2ac89e9a787357aaf74c3b56d5c07bc93ce899568a3eb17d9250c20f6c5f6c1e792ec9a2dcb715398d5a6ec6d5c54f586a00403a1af1de", - "derive_key": "1e0d7f3db8c414c97c6307cbda6cd27ac3b030949da8e23be1a1a924ad2f25b9d78038f7b198596c6cc4a9ccf93223c08722d684f240ff6569075ed81591fd93f9fff1110b3a75bc67e426012e5588959cc5a4c192173a03c00731cf84544f65a2fb9378989f72e9694a6a394a8a30997c2e67f95a504e631cd2c5f55246024761b245" - }, - { - "input_len": 4097, - "hash": "9b4052b38f1c5fc8b1f9ff7ac7b27cd242487b3d890d15c96a1c25b8aa0fb99505f91b0b5600a11251652eacfa9497b31cd3c409ce2e45cfe6c0a016967316c426bd26f619eab5d70af9a418b845c608840390f361630bd497b1ab44019316357c61dbe091ce72fc16dc340ac3d6e009e050b3adac4b5b2c92e722cffdc46501531956", - "keyed_hash": "00df940cd36bb9fa7cbbc3556744e0dbc8191401afe70520ba292ee3ca80abbc606db4976cfdd266ae0abf667d9481831ff12e0caa268e7d3e57260c0824115a54ce595ccc897786d9dcbf495599cfd90157186a46ec800a6763f1c59e36197e9939e900809f7077c102f888caaf864b253bc41eea812656d46742e4ea42769f89b83f", - "derive_key": "aca51029626b55fda7117b42a7c211f8c6e9ba4fe5b7a8ca922f34299500ead8a897f66a400fed9198fd61dd2d58d382458e64e100128075fc54b860934e8de2e84170734b06e1d212a117100820dbc48292d148afa50567b8b84b1ec336ae10d40c8c975a624996e12de31abbe135d9d159375739c333798a80c64ae895e51e22f3ad" - }, - { - "input_len": 5120, - "hash": "9cadc15fed8b5d854562b26a9536d9707cadeda9b143978f319ab34230535833acc61c8fdc114a2010ce8038c853e121e1544985133fccdd0a2d507e8e615e611e9a0ba4f47915f49e53d721816a9198e8b30f12d20ec3689989175f1bf7a300eee0d9321fad8da232ece6efb8e9fd81b42ad161f6b9550a069e66b11b40487a5f5059", - "keyed_hash": "2c493e48e9b9bf31e0553a22b23503c0a3388f035cece68eb438d22fa1943e209b4dc9209cd80ce7c1f7c9a744658e7e288465717ae6e56d5463d4f80cdb2ef56495f6a4f5487f69749af0c34c2cdfa857f3056bf8d807336a14d7b89bf62bef2fb54f9af6a546f818dc1e98b9e07f8a5834da50fa28fb5874af91bf06020d1bf0120e", - "derive_key": "7a7acac8a02adcf3038d74cdd1d34527de8a0fcc0ee3399d1262397ce5817f6055d0cefd84d9d57fe792d65a278fd20384ac6c30fdb340092f1a74a92ace99c482b28f0fc0ef3b923e56ade20c6dba47e49227166251337d80a037e987ad3a7f728b5ab6dfafd6e2ab1bd583a95d9c895ba9c2422c24ea0f62961f0dca45cad47bfa0d" - }, - { - "input_len": 5121, - "hash": "628bd2cb2004694adaab7bbd778a25df25c47b9d4155a55f8fbd79f2fe154cff96adaab0613a6146cdaabe498c3a94e529d3fc1da2bd08edf54ed64d40dcd6777647eac51d8277d70219a9694334a68bc8f0f23e20b0ff70ada6f844542dfa32cd4204ca1846ef76d811cdb296f65e260227f477aa7aa008bac878f72257484f2b6c95", - "keyed_hash": "6ccf1c34753e7a044db80798ecd0782a8f76f33563accaddbfbb2e0ea4b2d0240d07e63f13667a8d1490e5e04f13eb617aea16a8c8a5aaed1ef6fbde1b0515e3c81050b361af6ead126032998290b563e3caddeaebfab592e155f2e161fb7cba939092133f23f9e65245e58ec23457b78a2e8a125588aad6e07d7f11a85b88d375b72d", - "derive_key": "b07f01e518e702f7ccb44a267e9e112d403a7b3f4883a47ffbed4b48339b3c341a0add0ac032ab5aaea1e4e5b004707ec5681ae0fcbe3796974c0b1cf31a194740c14519273eedaabec832e8a784b6e7cfc2c5952677e6c3f2c3914454082d7eb1ce1766ac7d75a4d3001fc89544dd46b5147382240d689bbbaefc359fb6ae30263165" - }, - { - "input_len": 6144, - "hash": "3e2e5b74e048f3add6d21faab3f83aa44d3b2278afb83b80b3c35164ebeca2054d742022da6fdda444ebc384b04a54c3ac5839b49da7d39f6d8a9db03deab32aade156c1c0311e9b3435cde0ddba0dce7b26a376cad121294b689193508dd63151603c6ddb866ad16c2ee41585d1633a2cea093bea714f4c5d6b903522045b20395c83", - "keyed_hash": "3d6b6d21281d0ade5b2b016ae4034c5dec10ca7e475f90f76eac7138e9bc8f1dc35754060091dc5caf3efabe0603c60f45e415bb3407db67e6beb3d11cf8e4f7907561f05dace0c15807f4b5f389c841eb114d81a82c02a00b57206b1d11fa6e803486b048a5ce87105a686dee041207e095323dfe172df73deb8c9532066d88f9da7e", - "derive_key": "2a95beae63ddce523762355cf4b9c1d8f131465780a391286a5d01abb5683a1597099e3c6488aab6c48f3c15dbe1942d21dbcdc12115d19a8b8465fb54e9053323a9178e4275647f1a9927f6439e52b7031a0b465c861a3fc531527f7758b2b888cf2f20582e9e2c593709c0a44f9c6e0f8b963994882ea4168827823eef1f64169fef" - }, - { - "input_len": 6145, - "hash": "f1323a8631446cc50536a9f705ee5cb619424d46887f3c376c695b70e0f0507f18a2cfdd73c6e39dd75ce7c1c6e3ef238fd54465f053b25d21044ccb2093beb015015532b108313b5829c3621ce324b8e14229091b7c93f32db2e4e63126a377d2a63a3597997d4f1cba59309cb4af240ba70cebff9a23d5e3ff0cdae2cfd54e070022", - "keyed_hash": "9ac301e9e39e45e3250a7e3b3df701aa0fb6889fbd80eeecf28dbc6300fbc539f3c184ca2f59780e27a576c1d1fb9772e99fd17881d02ac7dfd39675aca918453283ed8c3169085ef4a466b91c1649cc341dfdee60e32231fc34c9c4e0b9a2ba87ca8f372589c744c15fd6f985eec15e98136f25beeb4b13c4e43dc84abcc79cd4646c", - "derive_key": "379bcc61d0051dd489f686c13de00d5b14c505245103dc040d9e4dd1facab8e5114493d029bdbd295aaa744a59e31f35c7f52dba9c3642f773dd0b4262a9980a2aef811697e1305d37ba9d8b6d850ef07fe41108993180cf779aeece363704c76483458603bbeeb693cffbbe5588d1f3535dcad888893e53d977424bb707201569a8d2" - }, - { - "input_len": 7168, - "hash": "61da957ec2499a95d6b8023e2b0e604ec7f6b50e80a9678b89d2628e99ada77a5707c321c83361793b9af62a40f43b523df1c8633cecb4cd14d00bdc79c78fca5165b863893f6d38b02ff7236c5a9a8ad2dba87d24c547cab046c29fc5bc1ed142e1de4763613bb162a5a538e6ef05ed05199d751f9eb58d332791b8d73fb74e4fce95", - "keyed_hash": "b42835e40e9d4a7f42ad8cc04f85a963a76e18198377ed84adddeaecacc6f3fca2f01d5277d69bb681c70fa8d36094f73ec06e452c80d2ff2257ed82e7ba348400989a65ee8daa7094ae0933e3d2210ac6395c4af24f91c2b590ef87d7788d7066ea3eaebca4c08a4f14b9a27644f99084c3543711b64a070b94f2c9d1d8a90d035d52", - "derive_key": "11c37a112765370c94a51415d0d651190c288566e295d505defdad895dae223730d5a5175a38841693020669c7638f40b9bc1f9f39cf98bda7a5b54ae24218a800a2116b34665aa95d846d97ea988bfcb53dd9c055d588fa21ba78996776ea6c40bc428b53c62b5f3ccf200f647a5aae8067f0ea1976391fcc72af1945100e2a6dcb88" - }, - { - "input_len": 7169, - "hash": "a003fc7a51754a9b3c7fae0367ab3d782dccf28855a03d435f8cfe74605e781798a8b20534be1ca9eb2ae2df3fae2ea60e48c6fb0b850b1385b5de0fe460dbe9d9f9b0d8db4435da75c601156df9d047f4ede008732eb17adc05d96180f8a73548522840779e6062d643b79478a6e8dbce68927f36ebf676ffa7d72d5f68f050b119c8", - "keyed_hash": "ed9b1a922c046fdb3d423ae34e143b05ca1bf28b710432857bf738bcedbfa5113c9e28d72fcbfc020814ce3f5d4fc867f01c8f5b6caf305b3ea8a8ba2da3ab69fabcb438f19ff11f5378ad4484d75c478de425fb8e6ee809b54eec9bdb184315dc856617c09f5340451bf42fd3270a7b0b6566169f242e533777604c118a6358250f54", - "derive_key": "554b0a5efea9ef183f2f9b931b7497995d9eb26f5c5c6dad2b97d62fc5ac31d99b20652c016d88ba2a611bbd761668d5eda3e568e940faae24b0d9991c3bd25a65f770b89fdcadabcb3d1a9c1cb63e69721cacf1ae69fefdcef1e3ef41bc5312ccc17222199e47a26552c6adc460cf47a72319cb5039369d0060eaea59d6c65130f1dd" - }, - { - "input_len": 8192, - "hash": "aae792484c8efe4f19e2ca7d371d8c467ffb10748d8a5a1ae579948f718a2a635fe51a27db045a567c1ad51be5aa34c01c6651c4d9b5b5ac5d0fd58cf18dd61a47778566b797a8c67df7b1d60b97b19288d2d877bb2df417ace009dcb0241ca1257d62712b6a4043b4ff33f690d849da91ea3bf711ed583cb7b7a7da2839ba71309bbf", - "keyed_hash": "dc9637c8845a770b4cbf76b8daec0eebf7dc2eac11498517f08d44c8fc00d58a4834464159dcbc12a0ba0c6d6eb41bac0ed6585cabfe0aca36a375e6c5480c22afdc40785c170f5a6b8a1107dbee282318d00d915ac9ed1143ad40765ec120042ee121cd2baa36250c618adaf9e27260fda2f94dea8fb6f08c04f8f10c78292aa46102", - "derive_key": "ad01d7ae4ad059b0d33baa3c01319dcf8088094d0359e5fd45d6aeaa8b2d0c3d4c9e58958553513b67f84f8eac653aeeb02ae1d5672dcecf91cd9985a0e67f4501910ecba25555395427ccc7241d70dc21c190e2aadee875e5aae6bf1912837e53411dabf7a56cbf8e4fb780432b0d7fe6cec45024a0788cf5874616407757e9e6bef7" - }, - { - "input_len": 8193, - "hash": "bab6c09cb8ce8cf459261398d2e7aef35700bf488116ceb94a36d0f5f1b7bc3bb2282aa69be089359ea1154b9a9286c4a56af4de975a9aa4a5c497654914d279bea60bb6d2cf7225a2fa0ff5ef56bbe4b149f3ed15860f78b4e2ad04e158e375c1e0c0b551cd7dfc82f1b155c11b6b3ed51ec9edb30d133653bb5709d1dbd55f4e1ff6", - "keyed_hash": "954a2a75420c8d6547e3ba5b98d963e6fa6491addc8c023189cc519821b4a1f5f03228648fd983aef045c2fa8290934b0866b615f585149587dda2299039965328835a2b18f1d63b7e300fc76ff260b571839fe44876a4eae66cbac8c67694411ed7e09df51068a22c6e67d6d3dd2cca8ff12e3275384006c80f4db68023f24eebba57", - "derive_key": "af1e0346e389b17c23200270a64aa4e1ead98c61695d917de7d5b00491c9b0f12f20a01d6d622edf3de026a4db4e4526225debb93c1237934d71c7340bb5916158cbdafe9ac3225476b6ab57a12357db3abbad7a26c6e66290e44034fb08a20a8d0ec264f309994d2810c49cfba6989d7abb095897459f5425adb48aba07c5fb3c83c0" - }, - { - "input_len": 16384, - "hash": "f875d6646de28985646f34ee13be9a576fd515f76b5b0a26bb324735041ddde49d764c270176e53e97bdffa58d549073f2c660be0e81293767ed4e4929f9ad34bbb39a529334c57c4a381ffd2a6d4bfdbf1482651b172aa883cc13408fa67758a3e47503f93f87720a3177325f7823251b85275f64636a8f1d599c2e49722f42e93893", - "keyed_hash": "9e9fc4eb7cf081ea7c47d1807790ed211bfec56aa25bb7037784c13c4b707b0df9e601b101e4cf63a404dfe50f2e1865bb12edc8fca166579ce0c70dba5a5c0fc960ad6f3772183416a00bd29d4c6e651ea7620bb100c9449858bf14e1ddc9ecd35725581ca5b9160de04060045993d972571c3e8f71e9d0496bfa744656861b169d65", - "derive_key": "160e18b5878cd0df1c3af85eb25a0db5344d43a6fbd7a8ef4ed98d0714c3f7e160dc0b1f09caa35f2f417b9ef309dfe5ebd67f4c9507995a531374d099cf8ae317542e885ec6f589378864d3ea98716b3bbb65ef4ab5e0ab5bb298a501f19a41ec19af84a5e6b428ecd813b1a47ed91c9657c3fba11c406bc316768b58f6802c9e9b57" - }, - { - "input_len": 31744, - "hash": "62b6960e1a44bcc1eb1a611a8d6235b6b4b78f32e7abc4fb4c6cdcce94895c47860cc51f2b0c28a7b77304bd55fe73af663c02d3f52ea053ba43431ca5bab7bfea2f5e9d7121770d88f70ae9649ea713087d1914f7f312147e247f87eb2d4ffef0ac978bf7b6579d57d533355aa20b8b77b13fd09748728a5cc327a8ec470f4013226f", - "keyed_hash": "efa53b389ab67c593dba624d898d0f7353ab99e4ac9d42302ee64cbf9939a4193a7258db2d9cd32a7a3ecfce46144114b15c2fcb68a618a976bd74515d47be08b628be420b5e830fade7c080e351a076fbc38641ad80c736c8a18fe3c66ce12f95c61c2462a9770d60d0f77115bbcd3782b593016a4e728d4c06cee4505cb0c08a42ec", - "derive_key": "39772aef80e0ebe60596361e45b061e8f417429d529171b6764468c22928e28e9759adeb797a3fbf771b1bcea30150a020e317982bf0d6e7d14dd9f064bc11025c25f31e81bd78a921db0174f03dd481d30e93fd8e90f8b2fee209f849f2d2a52f31719a490fb0ba7aea1e09814ee912eba111a9fde9d5c274185f7bae8ba85d300a2b" - }, - { - "input_len": 102400, - "hash": "bc3e3d41a1146b069abffad3c0d44860cf664390afce4d9661f7902e7943e085e01c59dab908c04c3342b816941a26d69c2605ebee5ec5291cc55e15b76146e6745f0601156c3596cb75065a9c57f35585a52e1ac70f69131c23d611ce11ee4ab1ec2c009012d236648e77be9295dd0426f29b764d65de58eb7d01dd42248204f45f8e", - "keyed_hash": "1c35d1a5811083fd7119f5d5d1ba027b4d01c0c6c49fb6ff2cf75393ea5db4a7f9dbdd3e1d81dcbca3ba241bb18760f207710b751846faaeb9dff8262710999a59b2aa1aca298a032d94eacfadf1aa192418eb54808db23b56e34213266aa08499a16b354f018fc4967d05f8b9d2ad87a7278337be9693fc638a3bfdbe314574ee6fc4", - "derive_key": "4652cff7a3f385a6103b5c260fc1593e13c778dbe608efb092fe7ee69df6e9c6d83a3e041bc3a48df2879f4a0a3ed40e7c961c73eff740f3117a0504c2dff4786d44fb17f1549eb0ba585e40ec29bf7732f0b7e286ff8acddc4cb1e23b87ff5d824a986458dcc6a04ac83969b80637562953df51ed1a7e90a7926924d2763778be8560" - } - ] -} \ No newline at end of file