Skip to main content

Chik vdf verification (wraps C++)

Project description

Chik VDF

Build PyPI PyPI - Format GitHub

CodeQL

Building a wheel

Compiling chikvdf requires cmake, boost and GMP/MPIR.

python3 -m venv venv
source venv/bin/activate

pip install wheel setuptools_scm pybind11
pip wheel .

The primary build process for this repository is to use GitHub Actions to build binary wheels for MacOS, Linux (x64 and aarch64), and Windows and publish them with a source wheel on PyPi. See .github/workflows/build.yml. CMake uses FetchContent to download pybind11. Building is then managed by cibuildwheel. Further installation is then available via pip install chikvdf e.g.

Building Timelord and related binaries

In addition to building the required binary and source wheels for Windows, MacOS and Linux, chikvdf can be used to compile vdf_client and vdf_bench. vdf_client is the core VDF process that completes the Proof of Time submitted to it by the Timelord. The repo also includes a benchmarking tool to get a sense of the iterations per second of a given CPU called vdf_bench. Try ./vdf_bench square_asm 250000 for an ips estimate.

To build vdf_client set the environment variable BUILD_VDF_CLIENT to "Y". export BUILD_VDF_CLIENT=Y.

Similarly, to build vdf_bench set the environment variable BUILD_VDF_BENCH to "Y". export BUILD_VDF_BENCH=Y.

This is currently automated via pip in the install-timelord.sh script in the chik-blockchain repository which depends on this repository.

If you're running a timelord, the following tests are available, depending of which type of timelord you are running:

./1weso_test, in case you're running in sanitizer_mode.

./2weso_test, in case you're running a timelord that extends the chain and you're running the slow algorithm.

./prover_test, in case you're running a timelord that extends the chain and you're running the fast algorithm.

Those tests will simulate the vdf_client and verify for correctness the produced proofs.

Contributing and workflow

Contributions are welcome and more details are available in chik-blockchain's CONTRIBUTING.md.

The master branch is the currently released latest version on PyPI. Note that at times chikvdf will be ahead of the release version that chik-blockchain requires in it's master/release version in preparation for a new chik-blockchain release. Please branch or fork master and then create a pull request to the master branch. Linear merging is enforced on master and merging requires a completed review. PRs will kick off a ci build and analysis of chikvdf at lgtm.com. Please make sure your build is passing and that it does not increase alerts at lgtm.

Background from prior VDF competitions

Copyright 2018 Ilya Gorodetskov generic@sundersoft.com

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.

Our VDF construction is described in classgroup.pdf. The implementation details about squaring and proving phrases are described below.

Main VDF Loop

The main VDF loop produces repeated squarings of the generator form (i.e. calculates y(n) = g^(2^n)) as fast as possible, until the program is interrupted. Sundersoft's entry from Chik's 2nd VDF contest is used, together with the fast reducer used in Pulmark's entry. This approach is described below:

The NUDUPL algorithm is used. The equations are based on cryptoslava's equations from the 1st contest. They were modified slightly to increase the level of parallelism.

The GCD is a custom implementation with scalar integers. There are two base cases: one uses a lookup table with continued fractions and the other uses the euclidean algorithm with a division table. The division table algorithm is slightly faster even though it has about 2x as many iterations.

After the base case, there is a 128 bit GCD that generates 64 bit cofactor matricies with Lehmer's algorithm. This is required to make the long integer multiplications efficient (Flint's implementation doesn't do this).

The GCD also implements Flint's partial xgcd function, but the output is slightly different. This implementation will always return an A value which is > the threshold and a B value which is <= the threshold. For a normal GCD, the threshold is 0, B is 0, and A is the GCD. Also the interfaces are slightly different.

Scalar integers are used for the GCD. I don't expect any speedup for the SIMD integers that were used in the last implementation since the GCD only uses 64x1024 multiplications, which are too small and have too high of a carry overhead for the SIMD version to be faster. In either case, most of the time seems to be spent in the base case so it shouldn't matter too much.

If SIMD integers are used with AVX-512, doubles have to be used because the multiplier sizes for doubles are significantly larger than for integers. There is an AVX-512 extension to support larger integer multiplications but no processor implements it yet. It should be possible to do a 50 bit multiply-add into a 100 bit accumulator with 4 fused multiply-adds if the accumulators have a special nonzero initial value and the inputs are scaled before the multiplication. This would make AVX-512 about 2.5x faster than scalar code for 1024x1024 integer multiplications (assuming the scalar code is unrolled and uses ADOX/ADCX/MULX properly, and the CPU can execute this at 1 cycle per iteration which it probably can't).

The GCD is parallelized by calculating the cofactors in a separate slave thread. The master thread will calculate the cofactor matricies and send them to the slave thread. Other calculations are also parallelized.

The VDF implementation from the first contest is still used as a fallback and is called about once every 5000 iterations. The GCD will encounter large quotients about this often and these are not implemented. This has a negligible effect on performance. Also, the NUDUPL case where A<=L is not implemented; it will fall back to the old implementation in this case (this never happens outside of the first 20 or so iterations).

There is also corruption detection by calculating C with a non-exact division and making sure the remainder is 0. This detected all injected random corruptions that I tested. No corruptions caused by bugs were observed during testing. This cannot correct for the sign of B being wrong.

GCD continued fraction lookup table

The is implemented in gcd_base_continued_fractions.h and asm_gcd_base_continued_fractions.h. The division table implementation is the same as the previous entry and was discussed there. Currently the division table is only used if AVX2 is enabled but it could be ported to SSE or scalar code easily. Both implementations have about the same performance.

The initial quotient sequence of gcd(a,b) is the same as the initial quotient sequence of gcd(a*2^n/b, 2^n) for any n. This is because the GCD quotients are the same as the continued fraction quotients of a/b, and the initial continued fraction quotients only depend on the initial bits of a/b. This makes it feasible to have a lookup table since it now only has one input.

a*2^n/b is calculated by doing a double precision division of a/b, and then truncating the lower bits. Some of the exponent bits are used in the table in addition to the fraction bits; this makes each slot of the table vary in size depending on what the exponent is. If the result is outside the table bounds, then the division result is floored to fall back to the euclidean algorithm (this is very rare).

The table is calculated by iterating all of the possible continued fractions that have a certain initial quotient sequence. Iteration ends when all of these fractions are either outside the table or they don't fully contain at least one slot of the table. Each slot that is fully contained by such a fraction is updated so that its quotient sequence equals the fraction's initial quotient sequence. Once this is complete, the cofactor matricies are calculated from the quotient sequences. Each cofactor matrix is 4 doubles.

The resulting code seems to have too many instructions so it doesn't perform very well. There might be some way to optimize it. It was written for SSE so that it would run on both processors.

This might work better on an FPGA possibly with low latency DRAM or SRAM (compared to the euclidean algorithm with a division table). There is no limit to the size of the table but doubling the latency would require the number of bits in the table to also be doubled to have the same performance.

Other GCD code

The gcd_128 function calculates a 128 bit GCD using Lehmer's algorithm. It is pretty straightforward and uses only unsigned arithmetic. Each cofactor matrix can only have two possible signs: [+ -; - +] or [- +; + -]. The gcd_unsigned function uses unsigned arithmetic and a jump table to apply the 64-bit cofactor matricies to the A and B values. It uses ADOX/ADCX/MULX if they are available and falls back to ADC/MUL otherwise. It will track the last known size of A to speed up the bit shifts required to get the top 128 bits of A.

No attempt was made to try to do the A and B long integer multiplications on a separate thread; I wouldn't expect any performance improvement from this.

Threads

There is a master thread and a slave thread. The slave thread only exists for each batch of 5000 or so squarings and is then destroyed and recreated for the next batch (this has no measurable overhead). If the original VDF is used as a fallback, the batch ends and the slave thread is destroyed.

Each thread has a 64-bit counter that only it can write to. Also, during a squaring iteration, it will not overwrite any value that it has previously written and transmitted to the other thread. Each squaring is split up into phases. Each thread will update its counter at the start of the phase (the counter can only be increased, not decreased). It can then wait on the other thread's counter to reach a certain value as part of a spin loop. If the spin loop takes too long, an error condition is raised and the batch ends; this should prevent any deadlocks from happening.

No CPU fences or atomics are required since each value can only be written to by one thread and since x86 enforces acquire/release ordering on all memory operations. Compiler memory fences are still required to prevent the compiler from caching or reordering memory operations.

The GCD master thread will increment the counter when a new cofactor matrix has been outputted. The slave thread will spin on this counter and then apply the cofactor matrix to the U or V vector to get a new U or V vector.

It was attempted to use modular arithmetic to calculate k directly but this slowed down the program due to GMP's modulo or integer multiply operations not having enough performance. This also makes the integer multiplications bigger.

The speedup isn't very high since most of the time is spent in the GCD base case and these can't be parallelized.

Generating proofs

The nested wesolowski proofs (n-wesolowski) are used to check the correctness of a VDF result. (Simple) Wesolowski proofs are described in A Survey of Two Verifiable Delay Functions. In order to prove h = g^(2^T), a n-wesolowski proof uses n intermediate simple wesolowski proofs. Given h, g, T, t1, t2, ..., tn, h1, h2, ..., hn, a correct n-wesolowski proof will verify the following:

h1 = g^(2^t1)
h2 = h1^(2^t2)
h3 = h2^(2^t3)
...
hn = h(n-1)^(2^tn)

Additionally, we must have:

t1 + t2 + ... + tn = T
hn = h

The algorithm will generate at most 64-wesolowski proofs. Some intermediates wesolowski proofs are stored in parallel with the main VDF loop. The goal is to have a n-wesolowski proof almost ready as soon as the main VDF loop finishes computing h = g^(2^T), for a T that we're interested in. We'll call a segment a tuple (y, x, T) for which we're interested in a simple wesolowski proof that y = x^(2^T). We'll call a segment finished when we've finished computing its proof.

Segmenets stored

We'll store finished segments of length 2^x for x being multiples of 2 greater than or equal to 16. The current implementation limits the maximum segment size to 2^30, but this can be increased if needed. Let P = 16+2*l. After each 2^P steps calculated by the main VDF loop, we'll store a segment proving that we've correctly done the 2^P steps. Formally, let x be the form after k*2^P steps, y be the form after (k+1)*2^P steps, for each k >= 0, for each P = 16+2*l. Then, we'll store a segment (y, x, 2^P), together with a simple wesolowski proof.

Segment threads

In order to finish a segment of length T=2^P, the number of iterations to run for is T/k + l*2^(k+1) and the intermediate storage required is T/(k*l), for some parameters k and l, as described in the paper. The squarings used to finish a segment are about 2 times as slow as the ones used by the main VDF loop. Even so, finishing a segment is much faster than producing its y value by the main VDF loop. This allows, by the time the main VDF loop finishes 2^16 more steps, to perform work on finishing multiple segments.

The parameters used in finishing segments, for T=2^16, are k=10 and l=1. Above that, parameters are k=12 and l=2^(P-18). Note that, for P >= 18, the intermediate storage needed for a segment is constant (i.e. 2^18/12 forms stored in memory).

Prover class is responsible to finish a segment. It implements pause/resume functionality, so its work can be paused, and later resumed from the point it stopped. For each unfinished segment generated by the main VDF loop, a Prover instance is created, which will eventually finish the segment.

Segment threads are responsible for deciding which Prover instance is currently running. In the current implementation, there are 3 segment threads (however the number is configurable), so at most 3 Prover instances will run at once, at different threads (other Provers will be paused). The segment threads will always pick the segments with the shortest length to run. In case of a tie, the segments received the earliest will have priority. Every time a new segment arrives, or a segment gets finished, some pausing/resuming of Provers is done, if needed. Pausing is done to have at most 3 Provers running at any time, whilst resuming is done if less than 3 Provers are working, but some Provers are paused.

All the segments of lengths 2^16, 2^18 and 2^20 will be finished relatively soon after the main VDF worker produced them, while the segments of length 2^22 and upwards will lag behind the main VDF worker a little. Eventually, all the higher size segments will be finished, the work on them being done repeatedly via pausing (when a smaller size segment arrives) and resuming (when all smaller size segments are finished).

Currently, 4 more segment threads are added after the main VDF loop finishes 500 million iterations (after about 1 hour of running). This is done to be completely sure even the very big sized segments will be finished. This optimisation is only allowed on machines supporting at least 16 concurrent threads.

Generating n-wesolowski proof

Let T an iteration we are interested in. Firstly, the main VDF Loop will need to calculate at least T iterations. Then, in order to get fast a n-wesolowski proof, we'll concatenate finished segments. We want the proof to be as short as possible, so we'll always pick finished segments of the maximum length possible. If such segments aren't finished, we'll choose lower length segments. A segment of length 2^(16 + 2*p) can always be replaced with 4 segments of length 2^(16 + 2*p - 2). The proof will be created shortly after the main VDF loop produced the result, as the 2^16 length segments will always be up to date with the main VDF loop (and, at worst case, we can always concatenate 2^16 length segments, if bigger sizes are not finished yet). It's possible after the concatenation that we'll still need to prove up to 2^16 iterations (no segment is able to cover anything less than 2^16). This last work is done in parallel with the main VDF loop, as an optimisation.

The program limits the proof size to 64-wesolowski. If number of iterations is very large, it's possible the concatenation won't fit into this. In this case, the program will attempt again to prove every minute, until there are enough large segments to fit the 64-wesolowski limit. However, almost in all cases, the concatenation will fit the 64-wesolowski limit in the first try.

Since the maximum segment size is 2^30 and we can use at most 64 segments in a concatenation, the program will prove at most 2^36 iterations. This can be increased if needed.

Intermediates storage

In order to finish segments, some intermediate values need to be stored for each segment. For each different possible segment length, we use a sliding window of length 20 to store those. Hence, for each segment length, we'll store only the intermediates values needed for the last 20 segments produced by the main VDF loop. Since finishing segments is faster than producing them by the main VDF loop, we assume the segment threads won't be behind by more than 20 segments from the main VDF loop, for each segment length. Thanks to the sliding window technique, the memory used will always be constant.

Generally, the main VDF loop performs all the storing, after computing a form we're interested in. However, since storing is very frequent and expensive (GMP operations), this will slow down the main VDF loop.

For the machines having at least 16 concurrent threads, an optimization is provided: the main VDF loop does only repeated squaring, without storing any form. After each 2^15 steps are performed, a new thread starts redoing the work for 2^15 more steps, this time storing the intermediate values as well. All the intermediates threads and the main VDF loop will work in parallel. The only purpose of the main VDF loop becomes now to produce the starting values for the intermediate threads, as fast as possible. The squarings used in the intermediates threads will be 2 times slower than the ones used in the main VDF loop. It's expected the intermediates will only lag behind the main VDF loop by 2^15 iterations, at any point: after 2^16 iterations are done by the main VDF loop, the first thread doing the first 2^15 intermediate values is already finished. Also, at that point, half of the work of the second thread doing the last 2^15 intermediates values should be already done.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

chikvdf-1.1.4.tar.gz (746.7 kB view details)

Uploaded Source

Built Distributions

chikvdf-1.1.4-cp312-cp312-win_amd64.whl (2.1 MB view details)

Uploaded CPython 3.12 Windows x86-64

chikvdf-1.1.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (477.0 kB view details)

Uploaded CPython 3.12 manylinux: glibc 2.17+ x86-64

chikvdf-1.1.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (397.8 kB view details)

Uploaded CPython 3.12 manylinux: glibc 2.17+ ARM64

chikvdf-1.1.4-cp312-cp312-macosx_11_0_x86_64.whl (341.7 kB view details)

Uploaded CPython 3.12 macOS 11.0+ x86-64

chikvdf-1.1.4-cp311-cp311-win_amd64.whl (2.1 MB view details)

Uploaded CPython 3.11 Windows x86-64

chikvdf-1.1.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (477.3 kB view details)

Uploaded CPython 3.11 manylinux: glibc 2.17+ x86-64

chikvdf-1.1.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (398.3 kB view details)

Uploaded CPython 3.11 manylinux: glibc 2.17+ ARM64

chikvdf-1.1.4-cp311-cp311-macosx_11_0_x86_64.whl (342.7 kB view details)

Uploaded CPython 3.11 macOS 11.0+ x86-64

chikvdf-1.1.4-cp310-cp310-win_amd64.whl (2.1 MB view details)

Uploaded CPython 3.10 Windows x86-64

chikvdf-1.1.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (396.5 kB view details)

Uploaded CPython 3.10 manylinux: glibc 2.17+ ARM64

chikvdf-1.1.4-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (462.6 kB view details)

Uploaded CPython 3.10 manylinux: glibc 2.12+ x86-64

chikvdf-1.1.4-cp310-cp310-macosx_11_0_x86_64.whl (341.3 kB view details)

Uploaded CPython 3.10 macOS 11.0+ x86-64

chikvdf-1.1.4-cp39-cp39-win_amd64.whl (2.1 MB view details)

Uploaded CPython 3.9 Windows x86-64

chikvdf-1.1.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (396.7 kB view details)

Uploaded CPython 3.9 manylinux: glibc 2.17+ ARM64

chikvdf-1.1.4-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (462.6 kB view details)

Uploaded CPython 3.9 manylinux: glibc 2.12+ x86-64

chikvdf-1.1.4-cp39-cp39-macosx_11_0_x86_64.whl (341.4 kB view details)

Uploaded CPython 3.9 macOS 11.0+ x86-64

chikvdf-1.1.4-cp38-cp38-win_amd64.whl (2.1 MB view details)

Uploaded CPython 3.8 Windows x86-64

chikvdf-1.1.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (396.4 kB view details)

Uploaded CPython 3.8 manylinux: glibc 2.17+ ARM64

chikvdf-1.1.4-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (462.5 kB view details)

Uploaded CPython 3.8 manylinux: glibc 2.12+ x86-64

chikvdf-1.1.4-cp38-cp38-macosx_11_0_x86_64.whl (341.3 kB view details)

Uploaded CPython 3.8 macOS 11.0+ x86-64

File details

Details for the file chikvdf-1.1.4.tar.gz.

File metadata

  • Download URL: chikvdf-1.1.4.tar.gz
  • Upload date:
  • Size: 746.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.0.0 CPython/3.12.3

File hashes

Hashes for chikvdf-1.1.4.tar.gz
Algorithm Hash digest
SHA256 23cf1838aa4744d0f5de57f1c9446ea26fb35fdc1435b286781477ec4464ab65
MD5 253e26c0870b6c5a00e6a4375380a5f7
BLAKE2b-256 5f8db9c92922b2c4a0e039b43fd650d4f102eafd5520fc08a1b2be98fdf50777

See more details on using hashes here.

File details

Details for the file chikvdf-1.1.4-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: chikvdf-1.1.4-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 2.1 MB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.0.0 CPython/3.12.3

File hashes

Hashes for chikvdf-1.1.4-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 502878b1dff4bf018e3660a917458d469edaf7508076fbc6ff94c4c393b7055a
MD5 7b74292badb937e646ce255f8a672b88
BLAKE2b-256 3b3fde0b04c84e65a4e15844d8bd3c35a4f741d1128926f416a33ef35b0ee101

See more details on using hashes here.

File details

Details for the file chikvdf-1.1.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for chikvdf-1.1.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 455e0cf5b3eb262da072106539a220daed851cd93b4edec8cf182f0a3626971a
MD5 c085e04430b73774596eeeb53b093075
BLAKE2b-256 da98b571536be5c979e2fdc1d2d9c712d553a2b4224ded899bc6bc6ae325457b

See more details on using hashes here.

File details

Details for the file chikvdf-1.1.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for chikvdf-1.1.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 39d41ad10b3197fd26d34c590c11b7c70cba57329b9bf1a10b4edcbac4509ac2
MD5 2c90d3378bd5e50d778619ca20051202
BLAKE2b-256 d462dba6ebd6e926875a56705cc392d464790067c0cd5f3b59706d007b17d375

See more details on using hashes here.

File details

Details for the file chikvdf-1.1.4-cp312-cp312-macosx_11_0_x86_64.whl.

File metadata

File hashes

Hashes for chikvdf-1.1.4-cp312-cp312-macosx_11_0_x86_64.whl
Algorithm Hash digest
SHA256 3ac6e0b73833f4101a229945df5263f8b9ae0227a8574a78fc9ce868690633e0
MD5 37e7b00d652c560f4d0385d006c25cd6
BLAKE2b-256 36816226b80e9120f37a4abb9e55574c1072c925bc3c97142b4748c028e6ca2c

See more details on using hashes here.

File details

Details for the file chikvdf-1.1.4-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: chikvdf-1.1.4-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 2.1 MB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.0.0 CPython/3.12.3

File hashes

Hashes for chikvdf-1.1.4-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 d9febb19a1abd0a93e21f8526893a483985e7a66d49e4b22844411a8e5a33d1a
MD5 cfe9d9e97e9c6521f233f0522c7310f2
BLAKE2b-256 4c8bde271863a812721c05e2b02932d875a34d148b37df06290220be8f38f064

See more details on using hashes here.

File details

Details for the file chikvdf-1.1.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for chikvdf-1.1.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 b0d7c11b40afbf97d7880010f05e34ba2c16339bcdcfd5026f384e1b6f688c12
MD5 8bc87244b3800f563a9041b326c93c1e
BLAKE2b-256 6f94f03f91a8b82c532d9de261e0c3bf8e4bb0c46e1bdc43cbb26969b720a917

See more details on using hashes here.

File details

Details for the file chikvdf-1.1.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for chikvdf-1.1.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 4604500340063a0e63768c745bcb94ca2ec6effcaa2ca09ab06b71b761854988
MD5 b5d0275ed3df6ba0a895b94e7c4c5281
BLAKE2b-256 6449101ea0b5823fb9e8997efeb8f3eaae5983b35a312fb4c027f7523103d773

See more details on using hashes here.

File details

Details for the file chikvdf-1.1.4-cp311-cp311-macosx_11_0_x86_64.whl.

File metadata

File hashes

Hashes for chikvdf-1.1.4-cp311-cp311-macosx_11_0_x86_64.whl
Algorithm Hash digest
SHA256 6b2e5c26bc1b2fe44a28027f48458377c8ca822423c32db98072ab8ce39c7b84
MD5 f162d13907c7af3577f348951f1863cf
BLAKE2b-256 8b5b92cedddb552b4a336fb9c6b78ff9f06a82f7f50a4ccf4ebdad72f507d300

See more details on using hashes here.

File details

Details for the file chikvdf-1.1.4-cp310-cp310-win_amd64.whl.

File metadata

  • Download URL: chikvdf-1.1.4-cp310-cp310-win_amd64.whl
  • Upload date:
  • Size: 2.1 MB
  • Tags: CPython 3.10, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.0.0 CPython/3.12.3

File hashes

Hashes for chikvdf-1.1.4-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 555373ae66660bcb0628a535f2184c390c65bf73ff585305b8cdd0ed54b6ce08
MD5 612ff973328378f3676e30e551d0e422
BLAKE2b-256 5b0929a315d38c9c34231603b157449464fcdf5c68f1c202f6bb4162c8700633

See more details on using hashes here.

File details

Details for the file chikvdf-1.1.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for chikvdf-1.1.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 e92068e212fae97d92cf3b5b834cef47032d389a8ee5835eb7227140bda47ccf
MD5 9189202a73175fbf56f331eafc49d349
BLAKE2b-256 9585089d2ef2f51d1c97b75fa1043300ed556ccc7b234230ed89c52f9028b18d

See more details on using hashes here.

File details

Details for the file chikvdf-1.1.4-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl.

File metadata

File hashes

Hashes for chikvdf-1.1.4-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 d9de811f0f5bf35c927234b65928f52dd40ab916bef270907714832c4cfda13c
MD5 0f17f8049eaed4be2320bccf49e15e63
BLAKE2b-256 f58f01c8312ae801f06ce048f69e4f96b4d10194d352caf9134acbc637edb5f7

See more details on using hashes here.

File details

Details for the file chikvdf-1.1.4-cp310-cp310-macosx_11_0_x86_64.whl.

File metadata

File hashes

Hashes for chikvdf-1.1.4-cp310-cp310-macosx_11_0_x86_64.whl
Algorithm Hash digest
SHA256 0d5586faff34833e461dbdc5cd8f1b107a2315bb790d237fb751e00302924e26
MD5 e6ac80149dd7b12f932fbd3fbbcb45bc
BLAKE2b-256 65b18a9b489aea1de02046a99b2ec37fcf8780e15009377da5123ddac0f6b8f6

See more details on using hashes here.

File details

Details for the file chikvdf-1.1.4-cp39-cp39-win_amd64.whl.

File metadata

  • Download URL: chikvdf-1.1.4-cp39-cp39-win_amd64.whl
  • Upload date:
  • Size: 2.1 MB
  • Tags: CPython 3.9, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.0.0 CPython/3.12.3

File hashes

Hashes for chikvdf-1.1.4-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 552f1a23a6d65f889d50f40a6b6b651f2e3d0f3626a8e60352985df0b4e60bc3
MD5 c38222ea300d0530c79e5ad54b0556de
BLAKE2b-256 7dd304b9c1d4e90571a2a34facb4db3afd2abc2e1a2c4fa9e0d4b19d3e9b65bf

See more details on using hashes here.

File details

Details for the file chikvdf-1.1.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for chikvdf-1.1.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 893b57032b9b6f3f406f53ce229142ddbe0ab834baf0e2bc123f5fc376cb74cc
MD5 e1a68e694e593fbd3405e1296463c69f
BLAKE2b-256 a01b9f0fe835d751ba474ed17c76261e873a6c21afc0010c6774a374642f6d50

See more details on using hashes here.

File details

Details for the file chikvdf-1.1.4-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl.

File metadata

File hashes

Hashes for chikvdf-1.1.4-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 92208c3e8bb2040511bd130f2c21996531b52806d14a37f6518bd02424da20f1
MD5 6aba35af896215797a91b9c2483e1d86
BLAKE2b-256 d718d393a957465f8384b680953a94ab636a341ee8febaf0754bc52c8b581acc

See more details on using hashes here.

File details

Details for the file chikvdf-1.1.4-cp39-cp39-macosx_11_0_x86_64.whl.

File metadata

File hashes

Hashes for chikvdf-1.1.4-cp39-cp39-macosx_11_0_x86_64.whl
Algorithm Hash digest
SHA256 652146911048e3ed9940bb378386773b00f216eaf6065670b8a536c19b54f1e6
MD5 108b16256a298113fcc75987ca085e39
BLAKE2b-256 88d3e857353028189eadbae8f1b1c2c4b32895226c7d0de81ddd6844235743ab

See more details on using hashes here.

File details

Details for the file chikvdf-1.1.4-cp38-cp38-win_amd64.whl.

File metadata

  • Download URL: chikvdf-1.1.4-cp38-cp38-win_amd64.whl
  • Upload date:
  • Size: 2.1 MB
  • Tags: CPython 3.8, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.0.0 CPython/3.12.3

File hashes

Hashes for chikvdf-1.1.4-cp38-cp38-win_amd64.whl
Algorithm Hash digest
SHA256 8da925e5faef19605cfc7bf6f9b4493e96a26a37d4ecf81ff9b282ee245c4950
MD5 6c63a64f4adf74d0a2f1da0b665eb3a7
BLAKE2b-256 d33a31a48cca8c24a769e1f4cc01922d6fb9217ba4b1f0427ee4a9fda9ad92c6

See more details on using hashes here.

File details

Details for the file chikvdf-1.1.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for chikvdf-1.1.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 b3e1a5ff866eac3a9c6a679631f28114c648f1f4cb26dbfe6aac4ef7bda6cb1c
MD5 d482e3a2a53da72794f49eac3053a7fb
BLAKE2b-256 30cb43f4d25f380e665ff43d075599058c735b69ab3698c5df16a45ced05bd0b

See more details on using hashes here.

File details

Details for the file chikvdf-1.1.4-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl.

File metadata

File hashes

Hashes for chikvdf-1.1.4-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 254349347398fec4e8c2e742efbd01bf27edd73fba3ee11aaa9be9c133d03ee9
MD5 8332faa61951ada0210dca6372ea1c7a
BLAKE2b-256 eb55b07525766b227f0d2a2274430c4ded7403d30282ea80ab25fab0111478a7

See more details on using hashes here.

File details

Details for the file chikvdf-1.1.4-cp38-cp38-macosx_11_0_x86_64.whl.

File metadata

File hashes

Hashes for chikvdf-1.1.4-cp38-cp38-macosx_11_0_x86_64.whl
Algorithm Hash digest
SHA256 6d26a0b5f5ef09999972e5ef600bea579eaaf8f1a0a43ec99a28dc46de1a7304
MD5 2cf4bcef0d9c7eb5cbf93ef7a97239c9
BLAKE2b-256 8781cbed1953229c2e928f5d4215a35f9ee03419c45bd323443aee0185b02b18

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page