pax_global_header 0000666 0000000 0000000 00000000064 15143052566 0014521 g ustar 00root root 0000000 0000000 52 comment=0e3f6fcc4061704b85de3e55a294ae62d7e55845 addchain-0.4.0/ 0000775 0000000 0000000 00000000000 15143052566 0013255 5 ustar 00root root 0000000 0000000 addchain-0.4.0/.github/ 0000775 0000000 0000000 00000000000 15143052566 0014615 5 ustar 00root root 0000000 0000000 addchain-0.4.0/.github/workflows/ 0000775 0000000 0000000 00000000000 15143052566 0016652 5 ustar 00root root 0000000 0000000 addchain-0.4.0/.github/workflows/ci.yml 0000664 0000000 0000000 00000003626 15143052566 0017777 0 ustar 00root root 0000000 0000000 name: ci permissions: contents: read on: push: branches: - master pull_request: schedule: - cron: "33 11 * * 6" jobs: test: strategy: matrix: go-version: [1.16.x, 1.17.x] platform: [ubuntu-latest] runs-on: ${{ matrix.platform }} steps: - name: Install Go uses: actions/setup-go@37335c7bb261b353407cff977110895fa0b4f7d8 # v2.1.3 with: go-version: ${{ matrix.go-version }} - name: Checkout code uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4 with: persist-credentials: false - name: Build run: go build ./... - name: Test run: go test -coverprofile=coverage.out -covermode=count ./... - name: Upload Coverage uses: codecov/codecov-action@51d810878be5422784e86451c0e7c14e5860ec47 # v2.0.2 with: token: ${{ secrets.CODECOV_TOKEN }} files: coverage.out flags: unittests lint: runs-on: ubuntu-latest steps: - name: Install Go uses: actions/setup-go@37335c7bb261b353407cff977110895fa0b4f7d8 # v2.1.3 with: go-version: 1.17.x - name: Configure Go Environment run: | echo GOPATH=${{ runner.workspace }} >> $GITHUB_ENV echo ${{ runner.workspace }}/bin >> $GITHUB_PATH - name: Checkout code uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4 with: persist-credentials: false - name: Bootstrap run: ./script/bootstrap - name: Lint run: ./script/lint - name: Generate run: ./script/generate -a - name: Git Status run: | git diff test -z "$(git status --porcelain)" - name: Format run: ./script/fmt - name: Git Status run: | git diff test -z "$(git status --porcelain)" addchain-0.4.0/.github/workflows/install.yml 0000664 0000000 0000000 00000001230 15143052566 0021037 0 ustar 00root root 0000000 0000000 name: install permissions: contents: read on: push: branches: - master pull_request: paths: - install.sh schedule: - cron: "47 18 * * *" jobs: install: strategy: matrix: platform: [ubuntu-latest, macos-latest, windows-latest] runs-on: ${{ matrix.platform }} steps: - name: Checkout code uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4 with: persist-credentials: false - name: Run Installer run: cat install.sh | sh -s -- -b ${{ runner.workspace }}/bin - name: Run Binary run: ${{ runner.workspace }}/bin/addchain -h addchain-0.4.0/.github/workflows/release.yml 0000664 0000000 0000000 00000001327 15143052566 0021020 0 ustar 00root root 0000000 0000000 name: release permissions: contents: write on: push: tags: - v* jobs: release: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4 with: fetch-depth: 0 persist-credentials: false - name: Set up Go uses: actions/setup-go@37335c7bb261b353407cff977110895fa0b4f7d8 # v2.1.3 with: go-version: 1.17.x - name: Run GoReleaser uses: goreleaser/goreleaser-action@5e15885530fb01d81d1f24e8a6f54ebbd0fed7eb # v2.5.0 with: version: v0.177.0 args: release --rm-dist env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} addchain-0.4.0/.github/workflows/stress.yml 0000664 0000000 0000000 00000002140 15143052566 0020715 0 ustar 00root root 0000000 0000000 name: stress permissions: contents: read on: workflow_dispatch: schedule: - cron: "42 10 * * 3" jobs: test: strategy: matrix: go-version: [1.17.x] platform: [ubuntu-latest] runs-on: ${{ matrix.platform }} steps: - name: Install Go uses: actions/setup-go@37335c7bb261b353407cff977110895fa0b4f7d8 # v2.1.3 with: go-version: ${{ matrix.go-version }} - name: Configure Go Environment run: | echo GOPATH=${{ runner.workspace }} >> $GITHUB_ENV echo ${{ runner.workspace }}/bin >> $GITHUB_PATH - name: Checkout code uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4 with: persist-credentials: false - name: Bootstrap run: ./script/bootstrap - name: Stress Test run: ./script/stress -c coverage.out - name: Upload Coverage uses: codecov/codecov-action@51d810878be5422784e86451c0e7c14e5860ec47 # v2.0.2 with: token: ${{ secrets.CODECOV_TOKEN }} files: coverage.out flags: stress addchain-0.4.0/.gitignore 0000664 0000000 0000000 00000000006 15143052566 0015241 0 ustar 00root root 0000000 0000000 dist/ addchain-0.4.0/.golangci.yml 0000664 0000000 0000000 00000001322 15143052566 0015637 0 ustar 00root root 0000000 0000000 linters: enable-all: true disable: - cyclop - exhaustivestruct - forbidigo - funlen - gochecknoglobals - gocognit - goerr113 - gomnd - ifshort - interfacer - lll - maligned - nlreturn - paralleltest - prealloc - predeclared - revive - testpackage - thelper - wastedassign - wrapcheck - wsl linters-settings: gci: local-prefixes: github.com/mmcloughlin/addchain issues: exclude-use-default: false exclude: # gosec: G304: Potential file inclusion via variable. - G304 # gosec: G306: Expect WriteFile permissions to be 0600 or less - G306 # gosec: G404: Use of weak random number generator - G404 addchain-0.4.0/.goreleaser.yml 0000664 0000000 0000000 00000000731 15143052566 0016207 0 ustar 00root root 0000000 0000000 before: hooks: - go mod tidy builds: - main: ./cmd/addchain env: - CGO_ENABLED=0 goos: - linux - windows - darwin goarch: - amd64 - arm64 ldflags: - -s -w - -X github.com/mmcloughlin/addchain/meta.buildversion={{ .Version }} archives: - format_overrides: - goos: windows format: zip files: - LICENSE* - CITATION* - README* release: draft: true prerelease: auto addchain-0.4.0/.zenodo.json 0000664 0000000 0000000 00000014013 15143052566 0015523 0 ustar 00root root 0000000 0000000 { "title": "mmcloughlin/addchain: v0.4.0", "description": "Cryptographic Addition Chain Generation in Go", "version": "0.4.0", "publication_date": "2021-10-30", "upload_type": "software", "access_right": "open", "license": "BSD-3-Clause", "creators": [ { "name": "McLoughlin, Michael Ben", "orcid": "0000-0003-2347-6258" } ], "related_identifiers": [ { "identifier": "https://github.com/mmcloughlin/addchain/tree/v0.4.0", "relation": "isSupplementTo", "scheme": "url" } ], "references": [ "Adamu Muhammad Noma, Abdullah Muhammed, Mohamad Afendee Mohamed and Zuriati Ahmad Zulkarnain. A Review on Heuristics for Addition Chain Problem: Towards Efficient Public Key Cryptosystems. Journal of Computer Science. 2017. https://thescipub.com/pdf/10.3844/jcssp.2017.275.289.pdf", "Diego F. Aranha, Paulo S. L. M. Barreto, Geovandro C. C. F. Pereira and Jefferson E. Ricardini. A note on high-security general-purpose elliptic curves. Cryptology ePrint Archive, Report 2013/647. 2013. https://eprint.iacr.org/2013/647", "Bos, Jurjen and Coster, Matthijs. Addition Chain Heuristics. In Advances in Cryptology --- CRYPTO' 89 Proceedings, pages 400--407. 1990. https://link.springer.com/content/pdf/10.1007/0-387-34805-0_37.pdf", "Martin Otto. Brauer addition-subtraction chains. PhD thesis, Universitat Paderborn. 2001. http://www.martin-otto.de/publications/docs/2001_MartinOtto_Diplom_BrauerAddition-SubtractionChains.pdf", "F Bergeron, J Berstel, S Brlek and C Duboc. Addition chains using continued fractions. Journal of Algorithms. 1989. http://www-igm.univ-mlv.fr/~berstel/Articles/1989AdditionChainDuboc.pdf", "Richard E. Crandall. Method and apparatus for public key exchange in a cryptographic system. US Patent 5,159,632. 1992. https://patents.google.com/patent/US5159632A", "Bernstein, Daniel J. Curve25519: New Diffie-Hellman Speed Records. In Public Key Cryptography - PKC 2006, pages 207--228. 2006. https://cr.yp.to/ecdh/curve25519-20060209.pdf", "Brian Smith. The Most Efficient Known Addition Chains for Field Element and Scalar Inversion for the Most Popular and Most Unpopular Elliptic Curves. 2017. https://briansmith.org/ecc-inversion-addition-chains-01 (accessed June 30, 2019)", "Bergeron, F., Berstel, J. and Brlek, S. Efficient computation of addition chains. Journal de theorie des nombres de Bordeaux. 1994. http://www.numdam.org/item/JTNB_1994__6_1_21_0", "Daniel J. Bernstein, Mike Hamburg, Anna Krasnova and Tanja Lange. Elligator: Elliptic-curve points indistinguishable from uniform random strings. Cryptology ePrint Archive, Report 2013/325. 2013. https://eprint.iacr.org/2013/325", "NIST. Digital Signature Standard (DSS). Federal Information Processing Standards Publication 186-2. 2000. https://csrc.nist.gov/csrc/media/publications/fips/186/2/archive/2000-01-27/documents/fips186-2.pdf", "Amadou Tall and Ali Yassin Sanghare. Efficient computation of addition-subtraction chains using generalized continued Fractions. Cryptology ePrint Archive, Report 2013/466. 2013. https://eprint.iacr.org/2013/466", "Kunihiro, Noboru and Yamamoto, Hirosuke. New Methods for Generating Short Addition Chains. IEICE Transactions on Fundamentals of Electronics Communications and Computer Sciences. 2000. https://pdfs.semanticscholar.org/b398/d10faca35af9ce5a6026458b251fd0a5640c.pdf", "Riad S. Wahby. kwantam/addchain. Github Repository. Apache License, Version 2.0. 2018. https://github.com/kwantam/addchain", "Mike Hamburg. Ed448-Goldilocks, a new elliptic curve. Cryptology ePrint Archive, Report 2015/625. 2015. https://eprint.iacr.org/2015/625", "Riad S. Wahby and Dan Boneh. Fast and simple constant-time hashing to the BLS12-381 elliptic curve. Cryptology ePrint Archive, Report 2019/403. 2019. https://eprint.iacr.org/2019/403", "Christophe Doche. Exponentiation. Handbook of Elliptic and Hyperelliptic Curve Cryptography, chapter 9. 2006. http://koclab.cs.ucsb.edu/teaching/ecc/eccPapers/Doche-ch09.pdf", "Knuth, Donald E. Evaluation of Powers. The Art of Computer Programming, Volume 2 (Third Edition): Seminumerical Algorithms, chapter 4.6.3. 1997. https://www-cs-faculty.stanford.edu/~knuth/taocp.html", "Ayan Nandy. Modifications of Bos and Coster’s Heuristics in search of a shorter addition chain for faster exponentiation. Masters thesis, Indian Statistical Institute Kolkata. 2011. http://library.isical.ac.in:8080/jspui/bitstream/10263/6441/1/DISS-285.pdf", "F. L. Ţiplea, S. Iftene, C. Hriţcu, I. Goriac, R. Gordân and E. Erbiceanu. MpNT: A Multi-Precision Number Theory Package, Number Theoretical Algorithms (I). Technical Report TR03-02, Faculty of Computer Science, \"Alexandru Ioan Cuza\" University, Iasi. 2003. https://profs.info.uaic.ro/~tr/tr03-02.pdf", "Daniel J. Bernstein and Tanja Lange. Security dangers of the NIST curves. 2013. https://cr.yp.to/talks/2013.09.16/slides-djb-20130916-a4.pdf", "Michael Scott, Naomi Benger, Manuel Charlemagne, Luis J. Dominguez Perez and Ezekiel J. Kachisa. On the final exponentiation for calculating pairings on ordinary elliptic curves. Cryptology ePrint Archive, Report 2008/490. 2008. https://eprint.iacr.org/2008/490", "Daniel J. Bernstein and Tanja Lange. SafeCurves: choosing safe curves for elliptic-curve cryptography. https://safecurves.cr.yp.to", "Certicom Research. SEC 2: Recommended Elliptic Curve Domain Parameters, Version 2.0. Standards for Efficient Cryptography 2. 2010. https://safecurves.cr.yp.to/www.secg.org/sec2-v2.pdf", "Jerome A. Solinas. Generalized Mersenne Primes. Technical Report CORR 99-39, Centre for Applied Cryptographic Research (CACR) at the University of Waterloo. 1999. http://cacr.uwaterloo.ca/techreports/1999/corr99-39.pdf", "Stam, Martijn. Speeding up subgroup cryptosystems. PhD thesis, Technische Universiteit Eindhoven. 2003. https://cr.yp.to/bib/2003/stam-thesis.pdf" ] } addchain-0.4.0/CITATION.bib 0000664 0000000 0000000 00000000675 15143052566 0015155 0 ustar 00root root 0000000 0000000 @misc{addchain, title = {addchain: Cryptographic Addition Chain Generation in Go}, author = {Michael B. McLoughlin}, year = 2021, month = oct, howpublished = {Repository \url{https://github.com/mmcloughlin/addchain}}, version = {0.4.0}, license = {BSD 3-Clause License}, doi = {10.5281/zenodo.5622943}, url = {https://doi.org/10.5281/zenodo.5622943}, } addchain-0.4.0/CITATION.cff 0000664 0000000 0000000 00000001270 15143052566 0015147 0 ustar 00root root 0000000 0000000 cff-version: 1.2.0 message: "If you use addchain in your work, a citation would be appreciated using the following metadata." title: "addchain: Cryptographic Addition Chain Generation in Go" authors: - family-names: "McLoughlin" given-names: "Michael Ben" orcid: "https://orcid.org/0000-0003-2347-6258" version: "0.4.0" date-released: "2021-10-30" license: BSD-3-Clause repository-code: https://github.com/mmcloughlin/addchain doi: "10.5281/zenodo.5622943" identifiers: - type: doi value: "10.5281/zenodo.4625263" description: "The concept DOI of the work." - type: doi value: "10.5281/zenodo.5622943" description: "The versioned DOI for version 0.4.0 of the work." addchain-0.4.0/LICENSE 0000664 0000000 0000000 00000002766 15143052566 0014275 0 ustar 00root root 0000000 0000000 BSD 3-Clause License Copyright (c) 2019, Michael McLoughlin All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. addchain-0.4.0/README.md 0000664 0000000 0000000 00000045510 15143052566 0014541 0 ustar 00root root 0000000 0000000
Cryptographic Addition Chain Generation in Go
`addchain` generates short addition chains for exponents of cryptographic interest with [results](#results) rivaling the best hand-optimized chains. Intended as a building block in elliptic curve or other cryptographic code generators. * Suite of algorithms from academic research: continued fractions, dictionary-based and Bos-Coster heuristics * Custom run-length techniques exploit structure of cryptographic exponents with excellent results on Solinas primes * Generic optimization methods eliminate redundant operations * Simple domain-specific language for addition chain computations * Command-line interface or library * Code generation and templated output support ## Table of Contents * [Background](#background) * [Results](#results) * [Usage](#usage) * [Command-line Interface](#command-line-interface) * [Library](#library) * [Algorithms](#algorithms) * [Binary](#binary) * [Continued Fractions](#continued-fractions) * [Bos-Coster Heuristics](#bos-coster-heuristics) * [Dictionary](#dictionary) * [Runs](#runs) * [Optimization](#optimization) * [Citing](#citing) * [Thanks](#thanks) * [Contributing](#contributing) * [License](#license) ## Background An [_addition chain_](https://en.wikipedia.org/wiki/Addition_chain) for a target integer _n_ is a sequence of numbers starting at 1 and ending at _n_ such that every term is a sum of two numbers appearing earlier in the sequence. For example, an addition chain for 29 is ``` 1, 2, 4, 8, 9, 17, 25, 29 ``` Addition chains arise in the optimization of exponentiation algorithms with fixed exponents. For example, the addition chain above corresponds to the following sequence of multiplications to computex29
x2 = x1 * x1 x4 = x2 * x2 x8 = x4 * x4 x9 = x1 * x8 x17 = x8 * x9 x25 = x8 * x17 x29 = x4 * x25An exponentiation algorithm for a fixed exponent _n_ reduces to finding a _minimal length addition chain_ for _n_. This is especially relevent in cryptography where exponentiation by huge fixed exponents forms a performance-critical component of finite-field arithmetic. In particular, constant-time inversion modulo a prime _p_ is performed by computing
xp-2 (mod p), thanks to [Fermat's Little
Theorem](https://en.wikipedia.org/wiki/Fermat%27_little_theorem). Square root
also reduces to exponentiation for some prime moduli. Finding short addition
chains for these exponents is one important part of high-performance finite
field implementations required for elliptic curve cryptography or RSA.
Minimal addition chain search is famously hard. No practical optimal
algorithm is known, especially for cryptographic exponents of size 256-bits
and up. Given its importance for the performance of cryptographic
implementations, implementers devote significant effort to hand-tune addition
chains. The goal of the `addchain` project is to match or exceed the best
hand-optimized addition chains using entirely automated approaches, building
on extensive academic research and applying new tweaks that exploit the
unique nature of cryptographic exponents.
## Results
The following table shows the results of the `addchain` library on popular
cryptographic exponents. For each one we also show the length of the [best
known hand-optimized addition chain](https://briansmith.org/ecc-inversion-addition-chains-01), and the
delta from the library result.
| Name | This Library | Best Known | Delta |
| ---- | -----------: | ---------: | ----: |
| [Curve25519 Field Inversion](doc/results.md#curve25519-field-inversion) | 266 | 265 | +1 |
| [NIST P-256 Field Inversion](doc/results.md#nist-p-256-field-inversion) | 266 | 266 | **+0** |
| [NIST P-384 Field Inversion](doc/results.md#nist-p-384-field-inversion) | 397 | 396 | +1 |
| [secp256k1 (Bitcoin) Field Inversion](doc/results.md#secp256k1-bitcoin-field-inversion) | 269 | 269 | **+0** |
| [Curve25519 Scalar Inversion](doc/results.md#curve25519-scalar-inversion) | 283 | 284 | **-1** |
| [NIST P-256 Scalar Inversion](doc/results.md#nist-p-256-scalar-inversion) | 294 | 292 | +2 |
| [NIST P-384 Scalar Inversion](doc/results.md#nist-p-384-scalar-inversion) | 434 | 433 | +1 |
| [secp256k1 (Bitcoin) Scalar Inversion](doc/results.md#secp256k1-bitcoin-scalar-inversion) | 293 | 290 | +3 |
See [full results listing](doc/results.md) for more detail and
results for less common exponents.
These results demonstrate that `addchain` is competitive with hand-optimized
chains, often with equivalent or better performance. Even when `addchain` is
slightly sub-optimal, it can still be considered valuable since it fully
automates a laborious manual process. As such, `addchain` can be trusted to
produce high quality results in an automated code generation tool.
## Usage
### Command-line Interface
Install a pre-compiled [release
binary](https://github.com/mmcloughlin/addchain/releases):
```
curl -sSfL https://git.io/addchain | sh -s -- -b /usr/local/bin
```
Alternatively build from source:
```
go install github.com/mmcloughlin/addchain/cmd/addchain@latest
```
Search for a curve25519 field inversion addition chain with:
```sh
addchain search '2^255 - 19 - 2'
```
Output:
```
addchain: expr: "2^255 - 19 - 2"
addchain: hex: 7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeb
addchain: dec: 57896044618658097711785492504343953926634992332820282019728792003956564819947
addchain: best: opt(runs(continued_fractions(dichotomic)))
addchain: cost: 266
_10 = 2*1
_11 = 1 + _10
_1100 = _11 << 2
_1111 = _11 + _1100
_11110000 = _1111 << 4
_11111111 = _1111 + _11110000
x10 = _11111111 << 2 + _11
x20 = x10 << 10 + x10
x30 = x20 << 10 + x10
x60 = x30 << 30 + x30
x120 = x60 << 60 + x60
x240 = x120 << 120 + x120
x250 = x240 << 10 + x10
return (x250 << 2 + 1) << 3 + _11
```
Next, you can [generate code from this addition chain](doc/gen.md).
### Library
Install:
```
go get -u github.com/mmcloughlin/addchain
```
Algorithms all conform to the [`alg.ChainAlgorithm`](https://pkg.go.dev/github.com/mmcloughlin/addchain/alg#ChainAlgorithm) or
[`alg.SequenceAlgorithm`](https://pkg.go.dev/github.com/mmcloughlin/addchain/alg#SequenceAlgorithm) interfaces and can be used directly. However the
most user-friendly method uses the [`alg/ensemble`](https://pkg.go.dev/github.com/mmcloughlin/addchain/alg/ensemble) package to
instantiate a sensible default set of algorithms and the [`alg/exec`](https://pkg.go.dev/github.com/mmcloughlin/addchain/alg/exec)
helper to execute them in parallel. The following code uses this method to
find an addition chain for curve25519 field inversion:
```go
func Example() {
// Target number: 2²⁵⁵ - 21.
n := new(big.Int)
n.SetString("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeb", 16)
// Default ensemble of algorithms.
algorithms := ensemble.Ensemble()
// Use parallel executor.
ex := exec.NewParallel()
results := ex.Execute(n, algorithms)
// Output best result.
best := 0
for i, r := range results {
if r.Err != nil {
log.Fatal(r.Err)
}
if len(results[i].Program) < len(results[best].Program) {
best = i
}
}
r := results[best]
fmt.Printf("best: %d\n", len(r.Program))
fmt.Printf("algorithm: %s\n", r.Algorithm)
// Output:
// best: 266
// algorithm: opt(runs(continued_fractions(dichotomic)))
}
```
## Algorithms
This section summarizes the algorithms implemented by `addchain` along with
references to primary literature. See the [bibliography](doc/bibliography.md)
for the complete references list.
### Binary
The [`alg/binary`](https://pkg.go.dev/github.com/mmcloughlin/addchain/alg/binary) package implements the addition chain equivalent
of the basic [square-and-multiply exponentiation
method](https://en.wikipedia.org/wiki/Exponentiation_by_squaring). It is
included for completeness, but is almost always outperformed by more advanced
algorithms below.
### Continued Fractions
The [`alg/contfrac`](https://pkg.go.dev/github.com/mmcloughlin/addchain/alg/contfrac) package implements the continued fractions
methods for addition sequence search introduced by
Bergeron-Berstel-Brlek-Duboc in 1989 and later extended. This approach
utilizes a decomposition of an addition chain akin to continued fractions,
namely
```
(1,..., k,..., n) = (1,...,n mod k,..., k) ⊗ (1,..., n/k) ⊕ (n mod k).
```
for certain special operators ⊗ and ⊕. This
decomposition lends itself to a recursive algorithm for efficient addition
sequence search, with results dependent on the _strategy_ for choosing the
auxillary integer _k_. The [`alg/contfrac`](https://pkg.go.dev/github.com/mmcloughlin/addchain/alg/contfrac) package provides a
laundry list of strategies from the literature: binary, co-binary,
dichotomic, dyadic, fermat, square-root and total.
#### References
* F Bergeron, J Berstel, S Brlek and C Duboc. Addition chains using continued fractions. Journal of Algorithms. 1989. http://www-igm.univ-mlv.fr/~berstel/Articles/1989AdditionChainDuboc.pdf
* Bergeron, F., Berstel, J. and Brlek, S. Efficient computation of addition chains. Journal de theorie des nombres de Bordeaux. 1994. http://www.numdam.org/item/JTNB_1994__6_1_21_0
* Amadou Tall and Ali Yassin Sanghare. Efficient computation of addition-subtraction chains using generalized continued Fractions. Cryptology ePrint Archive, Report 2013/466. 2013. https://eprint.iacr.org/2013/466
* Christophe Doche. Exponentiation. Handbook of Elliptic and Hyperelliptic Curve Cryptography, chapter 9. 2006. http://koclab.cs.ucsb.edu/teaching/ecc/eccPapers/Doche-ch09.pdf
### Bos-Coster Heuristics
Bos and Coster described an iterative algorithm for efficient addition
sequence generation in which at each step a heuristic proposes new numbers
for the sequence in such a way that the _maximum_ number always decreases.
The [original Bos-Coster paper](https://link.springer.com/content/pdf/10.1007/0-387-34805-0_37.pdf) defined four
heuristics: Approximation, Divison, Halving and Lucas. Package
[`alg/heuristic`](https://pkg.go.dev/github.com/mmcloughlin/addchain/alg/heuristic) implements a variation on these heuristics:
* **Approximation:** looks for two elements a, b in the current sequence with sum close to the largest element.
* **Halving:** applies when the target is at least twice as big as the next largest, and if so it will propose adding a sequence of doublings.
* **Delta Largest:** proposes adding the delta between the largest two entries in the current sequence.
Divison and Lucas are not implemented due to disparities in the literature
about their precise definition and poor results from early experiments.
Furthermore, this library does not apply weights to the heuristics as
suggested in the paper, rather it simply uses the first that applies. However
both of these remain [possible avenues for
improvement](https://github.com/mmcloughlin/addchain/issues/26).
#### References
* Bos, Jurjen and Coster, Matthijs. Addition Chain Heuristics. In Advances in Cryptology --- CRYPTO' 89 Proceedings, pages 400--407. 1990. https://link.springer.com/content/pdf/10.1007/0-387-34805-0_37.pdf
* Riad S. Wahby. kwantam/addchain. Github Repository. Apache License, Version 2.0. 2018. https://github.com/kwantam/addchain
* Christophe Doche. Exponentiation. Handbook of Elliptic and Hyperelliptic Curve Cryptography, chapter 9. 2006. http://koclab.cs.ucsb.edu/teaching/ecc/eccPapers/Doche-ch09.pdf
* Ayan Nandy. Modifications of Bos and Coster’s Heuristics in search of a shorter addition chain for faster exponentiation. Masters thesis, Indian Statistical Institute Kolkata. 2011. http://library.isical.ac.in:8080/jspui/bitstream/10263/6441/1/DISS-285.pdf
* F. L. Ţiplea, S. Iftene, C. Hriţcu, I. Goriac, R. Gordân and E. Erbiceanu. MpNT: A Multi-Precision Number Theory Package, Number Theoretical Algorithms (I). Technical Report TR03-02, Faculty of Computer Science, "Alexandru Ioan Cuza" University, Iasi. 2003. https://profs.info.uaic.ro/~tr/tr03-02.pdf
* Stam, Martijn. Speeding up subgroup cryptosystems. PhD thesis, Technische Universiteit Eindhoven. 2003. https://cr.yp.to/bib/2003/stam-thesis.pdf
### Dictionary
Dictionary methods decompose the binary representation of a target integer _n_ into a set of dictionary _terms_, such that _n_
may be written as a sum
n = ∑ 2ei difor exponents _e_ and elements _d_ from a dictionary _D_. Given such a decomposition we can construct an addition chain for _n_ by 1. Find a short addition _sequence_ containing every element of the dictionary _D_. Continued fractions and Bos-Coster heuristics can be used here. 2. Build _n_ from the dictionary terms according to the sum decomposition. The efficiency of this approach boils down to the decomposition method. The [`alg/dict`](https://pkg.go.dev/github.com/mmcloughlin/addchain/alg/dict) package provides: * **Fixed Window:** binary representation of _n_ is broken into fixed _k_-bit windows * **Sliding Window**: break _n_ into _k_-bit windows, skipping zeros where possible * **Run Length**: decompose _n_ into runs of 1s up to a maximal length * **Hybrid**: mix of sliding window and run length methods #### References * Martin Otto. Brauer addition-subtraction chains. PhD thesis, Universitat Paderborn. 2001. http://www.martin-otto.de/publications/docs/2001_MartinOtto_Diplom_BrauerAddition-SubtractionChains.pdf * Kunihiro, Noboru and Yamamoto, Hirosuke. New Methods for Generating Short Addition Chains. IEICE Transactions on Fundamentals of Electronics Communications and Computer Sciences. 2000. https://pdfs.semanticscholar.org/b398/d10faca35af9ce5a6026458b251fd0a5640c.pdf * Christophe Doche. Exponentiation. Handbook of Elliptic and Hyperelliptic Curve Cryptography, chapter 9. 2006. http://koclab.cs.ucsb.edu/teaching/ecc/eccPapers/Doche-ch09.pdf ### Runs The runs algorithm is a custom variant of the dictionary approach that decomposes a target into runs of ones. It leverages the observation that building a dictionary consisting of runs of 1s of lengths
l1, l2, ..., lk can itself be
reduced to:
1. Find an addition sequence containing the run lengths
li. As with dictionary approaches we can use
Bos-Coster heuristics and continued fractions here. However here we have the
advantage that the li are typically very _small_,
meaning that a wider range of algorithms can be brought to bear.
2. Use the addition sequence for the run lengths li
to build an addition sequence for the runs themselves
r(li) where r(e) = 2e-1. See
[`dict.RunsChain`](https://pkg.go.dev/github.com/mmcloughlin/addchain/alg/dict#RunsChain).
This approach has proved highly effective against cryptographic exponents
which frequently exhibit binary structure, such as those derived from
[Solinas primes](https://en.wikipedia.org/wiki/Solinas_prime).
> I have not seen this method discussed in the literature. Please help me find references to prior art if you know any.
### Optimization
Close inspection of addition chains produced by other algorithms revealed
cases of redundant computation. This motivated a final optimization pass over
addition chains to remove unecessary steps. The [`alg/opt`](https://pkg.go.dev/github.com/mmcloughlin/addchain/alg/opt) package
implements the following optimization:
1. Determine _all possible_ ways each element can be computed from those prior.
2. Count how many times each element is used where it is the _only possible_ way of computing that entry.
3. Prune elements that are always used in computations that have an alternative.
These micro-optimizations were vital in closing the gap between `addchain`'s
automated approaches and hand-optimized chains. This technique is reminiscent
of basic passes in optimizing compilers, raising the question of whether
other [compiler optimizations could apply to addition
chains](https://github.com/mmcloughlin/addchain/issues/24)?
> I have not seen this method discussed in the literature. Please help me find references to prior art if you know any.
## Citing
If you use `addchain` in your research a citation would be appreciated.
Citing a specific release is preferred, since they are [archived on
Zenodo](https://doi.org/10.5281/zenodo.4625263) and assigned a DOI. Please use the
following BibTeX to cite the most recent [0.4.0
release](https://github.com/mmcloughlin/addchain/releases/tag/v0.4.0).
```bib
@misc{addchain,
title = {addchain: Cryptographic Addition Chain Generation in Go},
author = {Michael B. McLoughlin},
year = 2021,
month = oct,
howpublished = {Repository \url{https://github.com/mmcloughlin/addchain}},
version = {0.4.0},
license = {BSD 3-Clause License},
doi = {10.5281/zenodo.5622943},
url = {https://doi.org/10.5281/zenodo.5622943},
}
```
If you need to cite a currently unreleased version please consider [filing an
issue](https://github.com/mmcloughlin/addchain/issues/new) to request a new
release, or to discuss an appropriate format for the citation.
## Thanks
Thank you to [Tom Dean](https://web.stanford.edu/~trdean/), [Riad
Wahby](https://wahby.org/), [Brian Smith](https://briansmith.org/) and
[str4d](https://github.com/str4d) for advice and encouragement. Thanks also to
[Damian Gryski](https://github.com/dgryski) and [Martin
Glancy](https://twitter.com/mglancy) for review.
## Contributing
Contributions to `addchain` are welcome:
* [Submit bug reports](https://github.com/mmcloughlin/addchain/issues/new) to
the issues page.
* Suggest [test cases](https://github.com/mmcloughlin/addchain/blob/e6c070065205efcaa02627ab1b23e8ce6aeea1db/internal/results/results.go#L62)
or update best-known hand-optimized results.
* Pull requests accepted. Please discuss in the [issues section](https://github.com/mmcloughlin/addchain/issues)
before starting significant work.
## License
`addchain` is available under the [BSD 3-Clause License](LICENSE).
addchain-0.4.0/acc/ 0000775 0000000 0000000 00000000000 15143052566 0014003 5 ustar 00root root 0000000 0000000 addchain-0.4.0/acc/acc.go 0000664 0000000 0000000 00000004105 15143052566 0015060 0 ustar 00root root 0000000 0000000 // Package acc implements the "addition chain calculator" language: a
// domain-specific language (DSL) for addition chain computation.
package acc
import (
"bytes"
"io"
"os"
"strings"
"github.com/mmcloughlin/addchain/acc/ir"
"github.com/mmcloughlin/addchain/acc/parse"
"github.com/mmcloughlin/addchain/acc/pass"
"github.com/mmcloughlin/addchain/acc/printer"
"github.com/mmcloughlin/addchain/internal/errutil"
)
// LoadFile is a convenience for loading an addition chain script from a file.
func LoadFile(filename string) (p *ir.Program, err error) {
f, err := os.Open(filename)
if err != nil {
return nil, err
}
defer errutil.CheckClose(&err, f)
return LoadReader(filename, f)
}
// LoadString is a convenience for loading and evaluating an addition chain
// script from a string.
func LoadString(src string) (*ir.Program, error) {
return LoadReader("string", strings.NewReader(src))
}
// LoadReader is a convenience for loading and evaluating an addition chain
// script.
func LoadReader(filename string, r io.Reader) (*ir.Program, error) {
// Parse to AST.
s, err := parse.Reader(filename, r)
if err != nil {
return nil, err
}
// Translate to IR.
p, err := Translate(s)
if err != nil {
return nil, err
}
// Evaluate the program.
if err := pass.Eval(p); err != nil {
return nil, err
}
return p, nil
}
// Write is a convenience for writing a program as an addition chain script.
func Write(w io.Writer, p *ir.Program) error {
// Build AST.
s, err := Build(p)
if err != nil {
return err
}
// Print.
if err := printer.Fprint(w, s); err != nil {
return err
}
return nil
}
// Save is a convenience for writing a program to a file.
func Save(filename string, p *ir.Program) (err error) {
f, err := os.Create(filename)
if err != nil {
return err
}
defer errutil.CheckClose(&err, f)
return Write(f, p)
}
// String is a convenience for obtaining a program as an addition chain script
// in string form.
func String(p *ir.Program) (string, error) {
var buf bytes.Buffer
if err := Write(&buf, p); err != nil {
return "", err
}
return buf.String(), nil
}
addchain-0.4.0/acc/acc_test.go 0000664 0000000 0000000 00000002661 15143052566 0016124 0 ustar 00root root 0000000 0000000 package acc
import (
"math/big"
"strings"
"testing"
"github.com/mmcloughlin/addchain/internal/prime"
)
func TestEvaluate(t *testing.T) {
cases := []struct {
Name string
Lines []string
Expect *big.Int
}{
{
Name: "add",
Lines: []string{
"1 add 1",
},
Expect: big.NewInt(2),
},
{
Name: "double",
Lines: []string{
"dbl 1",
},
Expect: big.NewInt(2),
},
{
Name: "shl",
Lines: []string{
"1 shl 3",
},
Expect: big.NewInt(8),
},
{
Name: "p25519-2",
Lines: []string{
"_1 = 1",
"_10 = _1 << 1",
"_1001 = _10 << 2 + _1",
"_1011 = _1001 + _10",
"x5 = _1011 << 1 + _1001",
"x10 = x5 << 5 + x5",
"x20 = x10 << 10 + x10",
"x40 = x20 << 20 + x20",
"x50 = x40 << 10 + x10",
"x100 = x50 << 50 + x50",
"x200 = x100 << 100 + x100",
"x250 = x200 << 50 + x50",
"return x250 << 5 + _1011",
},
Expect: new(big.Int).Sub(
prime.P25519.Int(),
big.NewInt(2),
),
},
}
for _, c := range cases {
c := c // scopelint
t.Run(c.Name, func(t *testing.T) {
src := strings.Join(c.Lines, "\n") + "\n"
// Load and evaluate.
p, err := LoadString(src)
if err != nil {
t.Fatal(err)
}
// Report.
for i, x := range p.Chain {
t.Logf("[%3d] bin=%b", i, x)
}
if err := p.Chain.Produces(c.Expect); err != nil {
t.Fatalf("chain does not produce %d: %s", c.Expect, err)
}
})
}
}
addchain-0.4.0/acc/ast/ 0000775 0000000 0000000 00000000000 15143052566 0014572 5 ustar 00root root 0000000 0000000 addchain-0.4.0/acc/ast/ast.go 0000664 0000000 0000000 00000002575 15143052566 0015721 0 ustar 00root root 0000000 0000000 // Package ast declares abstract syntax tree types for acc programs.
package ast
// Chain represents a sequence of acc statements for an addition chain
// computation.
type Chain struct {
Statements []Statement
}
// Statement assigns the result of an expression to a variable.
type Statement struct {
Name Identifier
Expr Expr
}
// Operator precedence range.
const (
LowestPrec = 0
HighestPrec = 4
)
// Expr is an expression.
type Expr interface {
Precedence() int
}
// Operand is an index into an addition chain.
type Operand int
// Precedence of this expression type.
func (Operand) Precedence() int { return HighestPrec }
// Identifier is a variable reference.
type Identifier string
// Precedence of this expression type.
func (Identifier) Precedence() int { return HighestPrec }
// Add expression.
type Add struct {
X, Y Expr
}
// Precedence of this expression type.
func (Add) Precedence() int { return 1 }
// Shift (repeated doubling) expression.
type Shift struct {
X Expr
S uint
}
// Precedence of this expression type.
func (Shift) Precedence() int { return 2 }
// Double expression.
type Double struct {
X Expr
}
// Precedence of this expression type.
func (Double) Precedence() int { return 3 }
// IsOp reports whether the expression is the result of an operator.
func IsOp(e Expr) bool {
switch e.(type) {
case Add, Shift, Double:
return true
}
return false
}
addchain-0.4.0/acc/ast/print.go 0000664 0000000 0000000 00000003120 15143052566 0016251 0 ustar 00root root 0000000 0000000 package ast
import (
"io"
"os"
"github.com/mmcloughlin/addchain/internal/errutil"
"github.com/mmcloughlin/addchain/internal/print"
)
// Print an AST node to standard out.
func Print(n interface{}) error {
return Fprint(os.Stdout, n)
}
// Fprint writes the AST node n to w.
func Fprint(w io.Writer, n interface{}) error {
p := newprinter(w)
p.node(n)
return p.Error()
}
type printer struct {
print.Printer
}
func newprinter(w io.Writer) *printer {
p := &printer{
Printer: print.New(w),
}
p.SetIndentString(". ")
return p
}
func (p *printer) node(n interface{}) {
switch n := n.(type) {
case *Chain:
p.enter("chain")
for _, stmt := range n.Statements {
p.statement(stmt)
}
p.leave()
case Statement:
p.statement(n)
case Operand:
p.Linef("operand(%d)", n)
case Identifier:
p.Linef("identifier(%q)", n)
case Add:
p.add(n)
case Double:
p.double(n)
case Shift:
p.shift(n)
default:
p.SetError(errutil.UnexpectedType(n))
}
}
func (p *printer) statement(stmt Statement) {
p.enter("statement")
p.Printf("name = ")
p.node(stmt.Name)
p.Printf("expr = ")
p.node(stmt.Expr)
p.leave()
}
func (p *printer) add(a Add) {
p.enter("add")
p.Printf("x = ")
p.node(a.X)
p.Printf("y = ")
p.node(a.Y)
p.leave()
}
func (p *printer) double(d Double) {
p.enter("double")
p.Printf("x = ")
p.node(d.X)
p.leave()
}
func (p *printer) shift(s Shift) {
p.enter("shift")
p.Linef("s = %d", s.S)
p.Printf("x = ")
p.node(s.X)
p.leave()
}
func (p *printer) enter(name string) {
p.Linef("%s {", name)
p.Indent()
}
func (p *printer) leave() {
p.Dedent()
p.Linef("}")
}
addchain-0.4.0/acc/build.go 0000664 0000000 0000000 00000007105 15143052566 0015434 0 ustar 00root root 0000000 0000000 package acc
import (
"fmt"
"github.com/mmcloughlin/addchain/acc/ast"
"github.com/mmcloughlin/addchain/acc/ir"
"github.com/mmcloughlin/addchain/acc/pass"
"github.com/mmcloughlin/addchain/internal/errutil"
)
// complexitylimit is the maximum number of operators the builder will allow an
// expression to have.
const complexitylimit = 5
// Build AST from a program in intermediate representation.
func Build(p *ir.Program) (*ast.Chain, error) {
// Run some analysis passes first.
err := pass.Exec(p,
pass.Func(pass.ReadCounts),
pass.NameByteValues,
pass.NameXRuns,
)
if err != nil {
return nil, err
}
// Delegate to builder.
b := newbuilder(p)
if err := b.process(); err != nil {
return nil, err
}
return b.chain, nil
}
type builder struct {
chain *ast.Chain
prog *ir.Program
expr map[int]ast.Expr
}
func newbuilder(p *ir.Program) *builder {
return &builder{
chain: &ast.Chain{},
prog: p,
expr: map[int]ast.Expr{},
}
}
func (b *builder) process() error {
insts := b.prog.Instructions
n := len(insts)
complexity := 0
for i := 0; i < n; i++ {
complexity++
inst := insts[i]
out := inst.Output
// Build expression for the result of this instruction.
e, err := b.operator(inst.Op)
if err != nil {
return err
}
b.expr[out.Index] = e
// If this output is read only by the following instruction, we don't need to
// commit it to a variable.
anon := out.Identifier == ""
usedonce := b.prog.ReadCount[out.Index] == 1
usednext := i+1 < n && ir.HasInput(insts[i+1].Op, out.Index)
if anon && usedonce && usednext && complexity < complexitylimit {
continue
}
// Otherwise write a statement for it.
b.commit(inst.Output)
complexity = 0
}
// Clear the name of the final statement.
b.chain.Statements[len(b.chain.Statements)-1].Name = ""
return nil
}
func (b *builder) operator(op ir.Op) (ast.Expr, error) {
switch o := op.(type) {
case ir.Add:
return b.add(o)
case ir.Double:
return ast.Double{
X: b.operand(o.X),
}, nil
case ir.Shift:
return ast.Shift{
X: b.operand(o.X),
S: o.S,
}, nil
default:
return nil, errutil.UnexpectedType(op)
}
}
func (b *builder) add(a ir.Add) (ast.Expr, error) {
// Addition operator construction is slightly delcate, since operand order
// determines ordering of execution. By the design of instruction processing
// above, the only way we can have multi-operator expressions is with a
// sequence of operands that are used only once and in the following
// instruction. This implies that only one of x and y can be an operator
// expression. In order to preserve execution order, whichever one that is
// needs to be the first operand.
x := b.operand(a.X)
y := b.operand(a.Y)
switch {
case ast.IsOp(x) && ast.IsOp(y):
return nil, errutil.AssertionFailure("only one of x and y should be an operator expression")
case ast.IsOp(y):
x, y = y, x
case ast.IsOp(x):
// Nothing, it's already the first operand.
}
return ast.Add{
X: x,
Y: y,
}, nil
}
func (b *builder) commit(op *ir.Operand) {
name := ast.Identifier(b.name(op))
stmt := ast.Statement{
Name: name,
Expr: b.operand(op),
}
b.chain.Statements = append(b.chain.Statements, stmt)
b.expr[op.Index] = name
}
// name returns the name for this operand. This is the identifier if available,
// otherwise a sensible default based on the index.
func (b *builder) name(op *ir.Operand) string {
if op.Identifier != "" {
return op.Identifier
}
return fmt.Sprintf("i%d", op.Index)
}
func (b *builder) operand(op *ir.Operand) ast.Expr {
e, ok := b.expr[op.Index]
if !ok {
return ast.Operand(op.Index)
}
return e
}
addchain-0.4.0/acc/decompile.go 0000664 0000000 0000000 00000002340 15143052566 0016272 0 ustar 00root root 0000000 0000000 package acc
import (
"github.com/mmcloughlin/addchain"
"github.com/mmcloughlin/addchain/acc/ir"
)
// Decompile an unrolled program into concise intermediate representation.
func Decompile(p addchain.Program) (*ir.Program, error) {
numreads := p.ReadCounts()
r := &ir.Program{}
for i := 0; i < len(p); i++ {
op := p[i]
// Regular addition.
if !op.IsDouble() {
r.AddInstruction(&ir.Instruction{
Output: ir.Index(i + 1),
Op: ir.Add{
X: ir.Index(op.I),
Y: ir.Index(op.J),
},
})
continue
}
// We have a double. Look ahead to see if this is a chain of doublings, which
// can be encoded as a shift. Note we can only follow the the doublings as
// long as the intermediate values are not required anywhere else later in the
// program.
j := i + 1
for ; j < len(p) && numreads[j] == 1 && p[j].I == j && p[j].J == j; j++ {
}
s := j - i
// Shift size 1 encoded as a double.
if s == 1 {
r.AddInstruction(&ir.Instruction{
Output: ir.Index(i + 1),
Op: ir.Double{
X: ir.Index(op.I),
},
})
continue
}
i = j - 1
r.AddInstruction(&ir.Instruction{
Output: ir.Index(i + 1),
Op: ir.Shift{
X: ir.Index(op.I),
S: uint(s),
},
})
}
return r, nil
}
addchain-0.4.0/acc/decompile_test.go 0000664 0000000 0000000 00000002502 15143052566 0017331 0 ustar 00root root 0000000 0000000 package acc
import (
"reflect"
"testing"
"github.com/mmcloughlin/addchain"
"github.com/mmcloughlin/addchain/acc/ir"
"github.com/mmcloughlin/addchain/acc/pass"
"github.com/mmcloughlin/addchain/internal/assert"
)
func TestDecompileExample(t *testing.T) {
p := addchain.Program{}
_, err := p.Double(0)
assert.NoError(t, err)
_, err = p.Add(0, 1)
assert.NoError(t, err)
_, err = p.Shift(1, 3)
assert.NoError(t, err)
_, err = p.Add(0, 5)
assert.NoError(t, err)
t.Log(p)
expect := &ir.Program{
Instructions: []*ir.Instruction{
{
Output: ir.Index(1),
Op: ir.Double{
X: ir.Index(0),
},
},
{
Output: ir.Index(2),
Op: ir.Add{
X: ir.Index(0),
Y: ir.Index(1),
},
},
{
Output: ir.Index(5),
Op: ir.Shift{
X: ir.Index(1),
S: 3,
},
},
{
Output: ir.Index(6),
Op: ir.Add{
X: ir.Index(0),
Y: ir.Index(5),
},
},
},
}
got, err := Decompile(p)
if err != nil {
t.Fatal()
}
t.Logf("got:\n%s", got)
if !reflect.DeepEqual(got, expect) {
t.Logf("expect:\n%s", expect)
t.Fatal("mismatch")
}
}
func TestDecompileRandom(t *testing.T) {
CheckRandom(t, func(t *testing.T, p addchain.Program) {
r, err := Decompile(p)
if err != nil {
t.Fatal(err)
}
if err := pass.Validate(r); err != nil {
t.Fatal(err)
}
})
}
addchain-0.4.0/acc/ir/ 0000775 0000000 0000000 00000000000 15143052566 0014415 5 ustar 00root root 0000000 0000000 addchain-0.4.0/acc/ir/ir.go 0000664 0000000 0000000 00000007436 15143052566 0015370 0 ustar 00root root 0000000 0000000 // Package ir declares an intermediate representation for acc programs.
package ir
import (
"fmt"
"strings"
"github.com/mmcloughlin/addchain"
)
// Program is a sequence of acc instructions.
type Program struct {
Instructions []*Instruction
// Pass/analysis results.
Operands map[int]*Operand
ReadCount map[int]int
Program addchain.Program
Chain addchain.Chain
Temporaries []string
}
// AddInstruction appends an instruction to the program.
func (p *Program) AddInstruction(i *Instruction) {
p.Instructions = append(p.Instructions, i)
}
// Output returns the output of the last instruction.
func (p Program) Output() *Operand {
last := len(p.Instructions) - 1
return p.Instructions[last].Output
}
// Clone returns a copy of p. Pass results are not copied and would need to be
// rerun on the clone.
func (p Program) Clone() *Program {
c := &Program{}
for _, inst := range p.Instructions {
c.Instructions = append(c.Instructions, inst.Clone())
}
return c
}
func (p Program) String() string {
var b strings.Builder
for _, i := range p.Instructions {
fmt.Fprintln(&b, i)
}
return b.String()
}
// Operand represents an element of an addition chain, with an optional
// identifier.
type Operand struct {
Identifier string
Index int
}
// NewOperand builds a named operand for index i.
func NewOperand(name string, i int) *Operand {
return &Operand{
Identifier: name,
Index: i,
}
}
// Index builds an unnamed operand for index i.
func Index(i int) *Operand {
return NewOperand("", i)
}
// One is the first element in the addition chain, which by definition always
// has the value 1.
var One = Index(0)
// Clone returns a copy of the operand.
func (o Operand) Clone() *Operand {
clone := o
return &clone
}
func (o Operand) String() string {
if len(o.Identifier) > 0 {
return o.Identifier
}
return fmt.Sprintf("[%d]", o.Index)
}
// Instruction assigns the result of an operation to an operand.
type Instruction struct {
Output *Operand
Op Op
}
// Operands returns the input and output operands.
func (i Instruction) Operands() []*Operand {
return append(i.Op.Inputs(), i.Output)
}
// Clone returns a copy of the instruction.
func (i Instruction) Clone() *Instruction {
return &Instruction{
Output: i.Output.Clone(),
Op: i.Op.Clone(),
}
}
func (i Instruction) String() string {
return fmt.Sprintf("%s \u2190 %s", i.Output, i.Op)
}
// Op is an operation.
type Op interface {
Inputs() []*Operand
Clone() Op
String() string
}
// Add is an addition operation.
type Add struct {
X, Y *Operand
}
// Inputs returns the addends.
func (a Add) Inputs() []*Operand {
return []*Operand{a.X, a.Y}
}
// Clone returns a copy of the operation.
func (a Add) Clone() Op {
return Add{
X: a.X.Clone(),
Y: a.Y.Clone(),
}
}
func (a Add) String() string {
return fmt.Sprintf("%s + %s", a.X, a.Y)
}
// Double is a double operation.
type Double struct {
X *Operand
}
// Inputs returns the operand.
func (d Double) Inputs() []*Operand {
return []*Operand{d.X}
}
// Clone returns a copy of the operation.
func (d Double) Clone() Op {
return Double{
X: d.X.Clone(),
}
}
func (d Double) String() string {
return fmt.Sprintf("2 * %s", d.X)
}
// Shift represents a shift-left operation, equivalent to repeat doubling.
type Shift struct {
X *Operand
S uint
}
// Inputs returns the operand to be shifted.
func (s Shift) Inputs() []*Operand {
return []*Operand{s.X}
}
// Clone returns a copy of the operation.
func (s Shift) Clone() Op {
return Shift{
X: s.X.Clone(),
S: s.S,
}
}
func (s Shift) String() string {
return fmt.Sprintf("%s \u226a %d", s.X, s.S)
}
// HasInput reports whether the given operation takes idx as an input.
func HasInput(op Op, idx int) bool {
for _, input := range op.Inputs() {
if input.Index == idx {
return true
}
}
return false
}
addchain-0.4.0/acc/parse/ 0000775 0000000 0000000 00000000000 15143052566 0015115 5 ustar 00root root 0000000 0000000 addchain-0.4.0/acc/parse/acc.peg 0000664 0000000 0000000 00000004405 15143052566 0016343 0 ustar 00root root 0000000 0000000 {
package parser
func exprs(first, rest interface{}) []ast.Expr {
es := []ast.Expr{first.(ast.Expr)}
if rest == nil {
return es
}
for _, i := range rest.([]interface{}) {
es = append(es, i.([]interface{})[3].(ast.Expr))
}
return es
}
}
// Chain
Chain <- as:Assignment* r:Return _ EOF {
ch := &ast.Chain{}
for _, a := range as.([]interface{}) {
ch.Statements = append(ch.Statements, a.(ast.Statement))
}
ch.Statements = append(ch.Statements, r.(ast.Statement))
return ch, nil
}
// Statements
Assignment <- _ n:Identifier _ '=' _ e:Expr _ EOL {
return ast.Statement{
Name: n.(ast.Identifier),
Expr: e.(ast.Expr),
}, nil
}
Return <- _ ("return" __)? e:Expr _ EOL? {
return ast.Statement{
Name: "",
Expr: e.(ast.Expr),
}, nil
}
// Expressions
Expr <- e:AddExpr {
return e, nil
}
AddExpr <- _ x:ShiftExpr rest:(_ AddOperator _ ShiftExpr)* _ {
es := exprs(x, rest)
r := es[0]
for _, e := range es[1:] {
r = ast.Add{
X: r,
Y: e,
}
}
return r, nil
}
ShiftExpr <- _ x:BaseExpr _ ShiftOperator _ s:UintLiteral _ {
return ast.Shift{
X: x.(ast.Expr),
S: s.(uint),
}, nil
} / _ DoubleOperator _ x:BaseExpr {
return ast.Double{
X: x.(ast.Expr),
}, nil
} / BaseExpr
BaseExpr <- ParenExpr / Operand
ParenExpr <- '(' _ e:Expr _ ')' {
return e, nil
}
// Operators
AddOperator <- '+' / "add"
ShiftOperator <- "<<" / "shl"
DoubleOperator <- '2' _ '*' / "dbl"
// Operands
Operand <- op:( One / Index / Identifier ) {
return op, nil
}
One <- '1' {
return ast.Operand(0), nil
}
Index <- '[' _ idx:UintLiteral _ ']' {
return ast.Operand(idx.(uint)), nil
}
// Identifiers
Identifier <- [a-zA-Z_] [a-zA-Z0-9_]* {
return ast.Identifier(c.text), nil
}
// Primitives
UintLiteral <- u64:Uint64Literal {
return uint(u64.(uint64)), nil
}
Uint64Literal <- (HexUintLiteral / OctalUintLiteral / DecimalUintLiteral) {
return strconv.ParseUint(string(c.text), 0, 64)
}
DecimalUintLiteral <- [0-9]+
HexUintLiteral <- "0x" [0-9a-fA-F]+
OctalUintLiteral <- '0' [0-7]+
// Character classes
__ <- Whitespace+
_ <- Whitespace*
Whitespace <- [ \t\r]
EOL <- '\n'
EOF <- !.
addchain-0.4.0/acc/parse/internal/ 0000775 0000000 0000000 00000000000 15143052566 0016731 5 ustar 00root root 0000000 0000000 addchain-0.4.0/acc/parse/internal/parser/ 0000775 0000000 0000000 00000000000 15143052566 0020225 5 ustar 00root root 0000000 0000000 addchain-0.4.0/acc/parse/internal/parser/zparser.go 0000664 0000000 0000000 00000150116 15143052566 0022246 0 ustar 00root root 0000000 0000000 // Code generated by pigeon; DO NOT EDIT.
package parser
import (
"bytes"
"errors"
"fmt"
"io"
"io/ioutil"
"math"
"os"
"sort"
"strconv"
"strings"
"sync"
"unicode"
"unicode/utf8"
"github.com/mmcloughlin/addchain/acc/ast"
)
func exprs(first, rest interface{}) []ast.Expr {
es := []ast.Expr{first.(ast.Expr)}
if rest == nil {
return es
}
for _, i := range rest.([]interface{}) {
es = append(es, i.([]interface{})[3].(ast.Expr))
}
return es
}
var g = &grammar{
rules: []*rule{
{
name: "Chain",
pos: position{line: 20, col: 1, offset: 290},
expr: &actionExpr{
pos: position{line: 20, col: 10, offset: 299},
run: (*parser).callonChain1,
expr: &seqExpr{
pos: position{line: 20, col: 10, offset: 299},
exprs: []interface{}{
&labeledExpr{
pos: position{line: 20, col: 10, offset: 299},
label: "as",
expr: &zeroOrMoreExpr{
pos: position{line: 20, col: 13, offset: 302},
expr: &ruleRefExpr{
pos: position{line: 20, col: 13, offset: 302},
name: "Assignment",
},
},
},
&labeledExpr{
pos: position{line: 20, col: 25, offset: 314},
label: "r",
expr: &ruleRefExpr{
pos: position{line: 20, col: 27, offset: 316},
name: "Return",
},
},
&ruleRefExpr{
pos: position{line: 20, col: 34, offset: 323},
name: "_",
},
&ruleRefExpr{
pos: position{line: 20, col: 36, offset: 325},
name: "EOF",
},
},
},
},
},
{
name: "Assignment",
pos: position{line: 31, col: 1, offset: 566},
expr: &actionExpr{
pos: position{line: 31, col: 15, offset: 580},
run: (*parser).callonAssignment1,
expr: &seqExpr{
pos: position{line: 31, col: 15, offset: 580},
exprs: []interface{}{
&ruleRefExpr{
pos: position{line: 31, col: 15, offset: 580},
name: "_",
},
&labeledExpr{
pos: position{line: 31, col: 17, offset: 582},
label: "n",
expr: &ruleRefExpr{
pos: position{line: 31, col: 19, offset: 584},
name: "Identifier",
},
},
&ruleRefExpr{
pos: position{line: 31, col: 30, offset: 595},
name: "_",
},
&litMatcher{
pos: position{line: 31, col: 32, offset: 597},
val: "=",
ignoreCase: false,
want: "\"=\"",
},
&ruleRefExpr{
pos: position{line: 31, col: 36, offset: 601},
name: "_",
},
&labeledExpr{
pos: position{line: 31, col: 38, offset: 603},
label: "e",
expr: &ruleRefExpr{
pos: position{line: 31, col: 40, offset: 605},
name: "Expr",
},
},
&ruleRefExpr{
pos: position{line: 31, col: 45, offset: 610},
name: "_",
},
&ruleRefExpr{
pos: position{line: 31, col: 47, offset: 612},
name: "EOL",
},
},
},
},
},
{
name: "Return",
pos: position{line: 38, col: 1, offset: 720},
expr: &actionExpr{
pos: position{line: 38, col: 11, offset: 730},
run: (*parser).callonReturn1,
expr: &seqExpr{
pos: position{line: 38, col: 11, offset: 730},
exprs: []interface{}{
&ruleRefExpr{
pos: position{line: 38, col: 11, offset: 730},
name: "_",
},
&zeroOrOneExpr{
pos: position{line: 38, col: 13, offset: 732},
expr: &seqExpr{
pos: position{line: 38, col: 14, offset: 733},
exprs: []interface{}{
&litMatcher{
pos: position{line: 38, col: 14, offset: 733},
val: "return",
ignoreCase: false,
want: "\"return\"",
},
&ruleRefExpr{
pos: position{line: 38, col: 23, offset: 742},
name: "__",
},
},
},
},
&labeledExpr{
pos: position{line: 38, col: 28, offset: 747},
label: "e",
expr: &ruleRefExpr{
pos: position{line: 38, col: 30, offset: 749},
name: "Expr",
},
},
&ruleRefExpr{
pos: position{line: 38, col: 35, offset: 754},
name: "_",
},
&zeroOrOneExpr{
pos: position{line: 38, col: 37, offset: 756},
expr: &ruleRefExpr{
pos: position{line: 38, col: 37, offset: 756},
name: "EOL",
},
},
},
},
},
},
{
name: "Expr",
pos: position{line: 47, col: 1, offset: 865},
expr: &actionExpr{
pos: position{line: 47, col: 9, offset: 873},
run: (*parser).callonExpr1,
expr: &labeledExpr{
pos: position{line: 47, col: 9, offset: 873},
label: "e",
expr: &ruleRefExpr{
pos: position{line: 47, col: 11, offset: 875},
name: "AddExpr",
},
},
},
},
{
name: "AddExpr",
pos: position{line: 51, col: 1, offset: 906},
expr: &actionExpr{
pos: position{line: 51, col: 12, offset: 917},
run: (*parser).callonAddExpr1,
expr: &seqExpr{
pos: position{line: 51, col: 12, offset: 917},
exprs: []interface{}{
&ruleRefExpr{
pos: position{line: 51, col: 12, offset: 917},
name: "_",
},
&labeledExpr{
pos: position{line: 51, col: 14, offset: 919},
label: "x",
expr: &ruleRefExpr{
pos: position{line: 51, col: 16, offset: 921},
name: "ShiftExpr",
},
},
&labeledExpr{
pos: position{line: 51, col: 26, offset: 931},
label: "rest",
expr: &zeroOrMoreExpr{
pos: position{line: 51, col: 31, offset: 936},
expr: &seqExpr{
pos: position{line: 51, col: 32, offset: 937},
exprs: []interface{}{
&ruleRefExpr{
pos: position{line: 51, col: 32, offset: 937},
name: "_",
},
&ruleRefExpr{
pos: position{line: 51, col: 34, offset: 939},
name: "AddOperator",
},
&ruleRefExpr{
pos: position{line: 51, col: 46, offset: 951},
name: "_",
},
&ruleRefExpr{
pos: position{line: 51, col: 48, offset: 953},
name: "ShiftExpr",
},
},
},
},
},
&ruleRefExpr{
pos: position{line: 51, col: 60, offset: 965},
name: "_",
},
},
},
},
},
{
name: "ShiftExpr",
pos: position{line: 63, col: 1, offset: 1134},
expr: &choiceExpr{
pos: position{line: 63, col: 14, offset: 1147},
alternatives: []interface{}{
&actionExpr{
pos: position{line: 63, col: 14, offset: 1147},
run: (*parser).callonShiftExpr2,
expr: &seqExpr{
pos: position{line: 63, col: 14, offset: 1147},
exprs: []interface{}{
&ruleRefExpr{
pos: position{line: 63, col: 14, offset: 1147},
name: "_",
},
&labeledExpr{
pos: position{line: 63, col: 16, offset: 1149},
label: "x",
expr: &ruleRefExpr{
pos: position{line: 63, col: 18, offset: 1151},
name: "BaseExpr",
},
},
&ruleRefExpr{
pos: position{line: 63, col: 27, offset: 1160},
name: "_",
},
&ruleRefExpr{
pos: position{line: 63, col: 29, offset: 1162},
name: "ShiftOperator",
},
&ruleRefExpr{
pos: position{line: 63, col: 43, offset: 1176},
name: "_",
},
&labeledExpr{
pos: position{line: 63, col: 45, offset: 1178},
label: "s",
expr: &ruleRefExpr{
pos: position{line: 63, col: 47, offset: 1180},
name: "UintLiteral",
},
},
&ruleRefExpr{
pos: position{line: 63, col: 59, offset: 1192},
name: "_",
},
},
},
},
&actionExpr{
pos: position{line: 68, col: 5, offset: 1279},
run: (*parser).callonShiftExpr13,
expr: &seqExpr{
pos: position{line: 68, col: 5, offset: 1279},
exprs: []interface{}{
&ruleRefExpr{
pos: position{line: 68, col: 5, offset: 1279},
name: "_",
},
&ruleRefExpr{
pos: position{line: 68, col: 7, offset: 1281},
name: "DoubleOperator",
},
&ruleRefExpr{
pos: position{line: 68, col: 22, offset: 1296},
name: "_",
},
&labeledExpr{
pos: position{line: 68, col: 24, offset: 1298},
label: "x",
expr: &ruleRefExpr{
pos: position{line: 68, col: 26, offset: 1300},
name: "BaseExpr",
},
},
},
},
},
&ruleRefExpr{
pos: position{line: 72, col: 5, offset: 1374},
name: "BaseExpr",
},
},
},
},
{
name: "BaseExpr",
pos: position{line: 74, col: 1, offset: 1384},
expr: &choiceExpr{
pos: position{line: 74, col: 13, offset: 1396},
alternatives: []interface{}{
&ruleRefExpr{
pos: position{line: 74, col: 13, offset: 1396},
name: "ParenExpr",
},
&ruleRefExpr{
pos: position{line: 74, col: 25, offset: 1408},
name: "Operand",
},
},
},
},
{
name: "ParenExpr",
pos: position{line: 76, col: 1, offset: 1417},
expr: &actionExpr{
pos: position{line: 76, col: 14, offset: 1430},
run: (*parser).callonParenExpr1,
expr: &seqExpr{
pos: position{line: 76, col: 14, offset: 1430},
exprs: []interface{}{
&litMatcher{
pos: position{line: 76, col: 14, offset: 1430},
val: "(",
ignoreCase: false,
want: "\"(\"",
},
&ruleRefExpr{
pos: position{line: 76, col: 18, offset: 1434},
name: "_",
},
&labeledExpr{
pos: position{line: 76, col: 20, offset: 1436},
label: "e",
expr: &ruleRefExpr{
pos: position{line: 76, col: 22, offset: 1438},
name: "Expr",
},
},
&ruleRefExpr{
pos: position{line: 76, col: 27, offset: 1443},
name: "_",
},
&litMatcher{
pos: position{line: 76, col: 29, offset: 1445},
val: ")",
ignoreCase: false,
want: "\")\"",
},
},
},
},
},
{
name: "AddOperator",
pos: position{line: 82, col: 1, offset: 1486},
expr: &choiceExpr{
pos: position{line: 82, col: 16, offset: 1501},
alternatives: []interface{}{
&litMatcher{
pos: position{line: 82, col: 16, offset: 1501},
val: "+",
ignoreCase: false,
want: "\"+\"",
},
&litMatcher{
pos: position{line: 82, col: 22, offset: 1507},
val: "add",
ignoreCase: false,
want: "\"add\"",
},
},
},
},
{
name: "ShiftOperator",
pos: position{line: 84, col: 1, offset: 1514},
expr: &choiceExpr{
pos: position{line: 84, col: 18, offset: 1531},
alternatives: []interface{}{
&litMatcher{
pos: position{line: 84, col: 18, offset: 1531},
val: "<<",
ignoreCase: false,
want: "\"<<\"",
},
&litMatcher{
pos: position{line: 84, col: 25, offset: 1538},
val: "shl",
ignoreCase: false,
want: "\"shl\"",
},
},
},
},
{
name: "DoubleOperator",
pos: position{line: 86, col: 1, offset: 1545},
expr: &choiceExpr{
pos: position{line: 86, col: 19, offset: 1563},
alternatives: []interface{}{
&seqExpr{
pos: position{line: 86, col: 19, offset: 1563},
exprs: []interface{}{
&litMatcher{
pos: position{line: 86, col: 19, offset: 1563},
val: "2",
ignoreCase: false,
want: "\"2\"",
},
&ruleRefExpr{
pos: position{line: 86, col: 23, offset: 1567},
name: "_",
},
&litMatcher{
pos: position{line: 86, col: 25, offset: 1569},
val: "*",
ignoreCase: false,
want: "\"*\"",
},
},
},
&litMatcher{
pos: position{line: 86, col: 31, offset: 1575},
val: "dbl",
ignoreCase: false,
want: "\"dbl\"",
},
},
},
},
{
name: "Operand",
pos: position{line: 90, col: 1, offset: 1595},
expr: &actionExpr{
pos: position{line: 90, col: 12, offset: 1606},
run: (*parser).callonOperand1,
expr: &labeledExpr{
pos: position{line: 90, col: 12, offset: 1606},
label: "op",
expr: &choiceExpr{
pos: position{line: 90, col: 17, offset: 1611},
alternatives: []interface{}{
&ruleRefExpr{
pos: position{line: 90, col: 17, offset: 1611},
name: "One",
},
&ruleRefExpr{
pos: position{line: 90, col: 23, offset: 1617},
name: "Index",
},
&ruleRefExpr{
pos: position{line: 90, col: 31, offset: 1625},
name: "Identifier",
},
},
},
},
},
},
{
name: "One",
pos: position{line: 94, col: 1, offset: 1662},
expr: &actionExpr{
pos: position{line: 94, col: 8, offset: 1669},
run: (*parser).callonOne1,
expr: &litMatcher{
pos: position{line: 94, col: 8, offset: 1669},
val: "1",
ignoreCase: false,
want: "\"1\"",
},
},
},
{
name: "Index",
pos: position{line: 98, col: 1, offset: 1709},
expr: &actionExpr{
pos: position{line: 98, col: 10, offset: 1718},
run: (*parser).callonIndex1,
expr: &seqExpr{
pos: position{line: 98, col: 10, offset: 1718},
exprs: []interface{}{
&litMatcher{
pos: position{line: 98, col: 10, offset: 1718},
val: "[",
ignoreCase: false,
want: "\"[\"",
},
&ruleRefExpr{
pos: position{line: 98, col: 14, offset: 1722},
name: "_",
},
&labeledExpr{
pos: position{line: 98, col: 16, offset: 1724},
label: "idx",
expr: &ruleRefExpr{
pos: position{line: 98, col: 20, offset: 1728},
name: "UintLiteral",
},
},
&ruleRefExpr{
pos: position{line: 98, col: 32, offset: 1740},
name: "_",
},
&litMatcher{
pos: position{line: 98, col: 34, offset: 1742},
val: "]",
ignoreCase: false,
want: "\"]\"",
},
},
},
},
},
{
name: "Identifier",
pos: position{line: 104, col: 1, offset: 1807},
expr: &actionExpr{
pos: position{line: 104, col: 15, offset: 1821},
run: (*parser).callonIdentifier1,
expr: &seqExpr{
pos: position{line: 104, col: 15, offset: 1821},
exprs: []interface{}{
&charClassMatcher{
pos: position{line: 104, col: 15, offset: 1821},
val: "[a-zA-Z_]",
chars: []rune{'_'},
ranges: []rune{'a', 'z', 'A', 'Z'},
ignoreCase: false,
inverted: false,
},
&zeroOrMoreExpr{
pos: position{line: 104, col: 25, offset: 1831},
expr: &charClassMatcher{
pos: position{line: 104, col: 25, offset: 1831},
val: "[a-zA-Z0-9_]",
chars: []rune{'_'},
ranges: []rune{'a', 'z', 'A', 'Z', '0', '9'},
ignoreCase: false,
inverted: false,
},
},
},
},
},
},
{
name: "UintLiteral",
pos: position{line: 110, col: 1, offset: 1904},
expr: &actionExpr{
pos: position{line: 110, col: 16, offset: 1919},
run: (*parser).callonUintLiteral1,
expr: &labeledExpr{
pos: position{line: 110, col: 16, offset: 1919},
label: "u64",
expr: &ruleRefExpr{
pos: position{line: 110, col: 20, offset: 1923},
name: "Uint64Literal",
},
},
},
},
{
name: "Uint64Literal",
pos: position{line: 114, col: 1, offset: 1977},
expr: &actionExpr{
pos: position{line: 114, col: 18, offset: 1994},
run: (*parser).callonUint64Literal1,
expr: &choiceExpr{
pos: position{line: 114, col: 19, offset: 1995},
alternatives: []interface{}{
&ruleRefExpr{
pos: position{line: 114, col: 19, offset: 1995},
name: "HexUintLiteral",
},
&ruleRefExpr{
pos: position{line: 114, col: 36, offset: 2012},
name: "OctalUintLiteral",
},
&ruleRefExpr{
pos: position{line: 114, col: 55, offset: 2031},
name: "DecimalUintLiteral",
},
},
},
},
},
{
name: "DecimalUintLiteral",
pos: position{line: 118, col: 1, offset: 2108},
expr: &oneOrMoreExpr{
pos: position{line: 118, col: 23, offset: 2130},
expr: &charClassMatcher{
pos: position{line: 118, col: 23, offset: 2130},
val: "[0-9]",
ranges: []rune{'0', '9'},
ignoreCase: false,
inverted: false,
},
},
},
{
name: "HexUintLiteral",
pos: position{line: 120, col: 1, offset: 2138},
expr: &seqExpr{
pos: position{line: 120, col: 19, offset: 2156},
exprs: []interface{}{
&litMatcher{
pos: position{line: 120, col: 19, offset: 2156},
val: "0x",
ignoreCase: false,
want: "\"0x\"",
},
&oneOrMoreExpr{
pos: position{line: 120, col: 24, offset: 2161},
expr: &charClassMatcher{
pos: position{line: 120, col: 24, offset: 2161},
val: "[0-9a-fA-F]",
ranges: []rune{'0', '9', 'a', 'f', 'A', 'F'},
ignoreCase: false,
inverted: false,
},
},
},
},
},
{
name: "OctalUintLiteral",
pos: position{line: 122, col: 1, offset: 2175},
expr: &seqExpr{
pos: position{line: 122, col: 21, offset: 2195},
exprs: []interface{}{
&litMatcher{
pos: position{line: 122, col: 21, offset: 2195},
val: "0",
ignoreCase: false,
want: "\"0\"",
},
&oneOrMoreExpr{
pos: position{line: 122, col: 25, offset: 2199},
expr: &charClassMatcher{
pos: position{line: 122, col: 25, offset: 2199},
val: "[0-7]",
ranges: []rune{'0', '7'},
ignoreCase: false,
inverted: false,
},
},
},
},
},
{
name: "__",
pos: position{line: 126, col: 1, offset: 2229},
expr: &oneOrMoreExpr{
pos: position{line: 126, col: 7, offset: 2235},
expr: &ruleRefExpr{
pos: position{line: 126, col: 7, offset: 2235},
name: "Whitespace",
},
},
},
{
name: "_",
pos: position{line: 127, col: 1, offset: 2247},
expr: &zeroOrMoreExpr{
pos: position{line: 127, col: 6, offset: 2252},
expr: &ruleRefExpr{
pos: position{line: 127, col: 6, offset: 2252},
name: "Whitespace",
},
},
},
{
name: "Whitespace",
pos: position{line: 129, col: 1, offset: 2265},
expr: &charClassMatcher{
pos: position{line: 129, col: 15, offset: 2279},
val: "[ \\t\\r]",
chars: []rune{' ', '\t', '\r'},
ignoreCase: false,
inverted: false,
},
},
{
name: "EOL",
pos: position{line: 130, col: 1, offset: 2287},
expr: &litMatcher{
pos: position{line: 130, col: 8, offset: 2294},
val: "\n",
ignoreCase: false,
want: "\"\\n\"",
},
},
{
name: "EOF",
pos: position{line: 131, col: 1, offset: 2299},
expr: ¬Expr{
pos: position{line: 131, col: 8, offset: 2306},
expr: &anyMatcher{
line: 131, col: 9, offset: 2307,
},
},
},
},
}
func (c *current) onChain1(as, r interface{}) (interface{}, error) {
ch := &ast.Chain{}
for _, a := range as.([]interface{}) {
ch.Statements = append(ch.Statements, a.(ast.Statement))
}
ch.Statements = append(ch.Statements, r.(ast.Statement))
return ch, nil
}
func (p *parser) callonChain1() (interface{}, error) {
stack := p.vstack[len(p.vstack)-1]
_ = stack
return p.cur.onChain1(stack["as"], stack["r"])
}
func (c *current) onAssignment1(n, e interface{}) (interface{}, error) {
return ast.Statement{
Name: n.(ast.Identifier),
Expr: e.(ast.Expr),
}, nil
}
func (p *parser) callonAssignment1() (interface{}, error) {
stack := p.vstack[len(p.vstack)-1]
_ = stack
return p.cur.onAssignment1(stack["n"], stack["e"])
}
func (c *current) onReturn1(e interface{}) (interface{}, error) {
return ast.Statement{
Name: "",
Expr: e.(ast.Expr),
}, nil
}
func (p *parser) callonReturn1() (interface{}, error) {
stack := p.vstack[len(p.vstack)-1]
_ = stack
return p.cur.onReturn1(stack["e"])
}
func (c *current) onExpr1(e interface{}) (interface{}, error) {
return e, nil
}
func (p *parser) callonExpr1() (interface{}, error) {
stack := p.vstack[len(p.vstack)-1]
_ = stack
return p.cur.onExpr1(stack["e"])
}
func (c *current) onAddExpr1(x, rest interface{}) (interface{}, error) {
es := exprs(x, rest)
r := es[0]
for _, e := range es[1:] {
r = ast.Add{
X: r,
Y: e,
}
}
return r, nil
}
func (p *parser) callonAddExpr1() (interface{}, error) {
stack := p.vstack[len(p.vstack)-1]
_ = stack
return p.cur.onAddExpr1(stack["x"], stack["rest"])
}
func (c *current) onShiftExpr2(x, s interface{}) (interface{}, error) {
return ast.Shift{
X: x.(ast.Expr),
S: s.(uint),
}, nil
}
func (p *parser) callonShiftExpr2() (interface{}, error) {
stack := p.vstack[len(p.vstack)-1]
_ = stack
return p.cur.onShiftExpr2(stack["x"], stack["s"])
}
func (c *current) onShiftExpr13(x interface{}) (interface{}, error) {
return ast.Double{
X: x.(ast.Expr),
}, nil
}
func (p *parser) callonShiftExpr13() (interface{}, error) {
stack := p.vstack[len(p.vstack)-1]
_ = stack
return p.cur.onShiftExpr13(stack["x"])
}
func (c *current) onParenExpr1(e interface{}) (interface{}, error) {
return e, nil
}
func (p *parser) callonParenExpr1() (interface{}, error) {
stack := p.vstack[len(p.vstack)-1]
_ = stack
return p.cur.onParenExpr1(stack["e"])
}
func (c *current) onOperand1(op interface{}) (interface{}, error) {
return op, nil
}
func (p *parser) callonOperand1() (interface{}, error) {
stack := p.vstack[len(p.vstack)-1]
_ = stack
return p.cur.onOperand1(stack["op"])
}
func (c *current) onOne1() (interface{}, error) {
return ast.Operand(0), nil
}
func (p *parser) callonOne1() (interface{}, error) {
stack := p.vstack[len(p.vstack)-1]
_ = stack
return p.cur.onOne1()
}
func (c *current) onIndex1(idx interface{}) (interface{}, error) {
return ast.Operand(idx.(uint)), nil
}
func (p *parser) callonIndex1() (interface{}, error) {
stack := p.vstack[len(p.vstack)-1]
_ = stack
return p.cur.onIndex1(stack["idx"])
}
func (c *current) onIdentifier1() (interface{}, error) {
return ast.Identifier(c.text), nil
}
func (p *parser) callonIdentifier1() (interface{}, error) {
stack := p.vstack[len(p.vstack)-1]
_ = stack
return p.cur.onIdentifier1()
}
func (c *current) onUintLiteral1(u64 interface{}) (interface{}, error) {
return uint(u64.(uint64)), nil
}
func (p *parser) callonUintLiteral1() (interface{}, error) {
stack := p.vstack[len(p.vstack)-1]
_ = stack
return p.cur.onUintLiteral1(stack["u64"])
}
func (c *current) onUint64Literal1() (interface{}, error) {
return strconv.ParseUint(string(c.text), 0, 64)
}
func (p *parser) callonUint64Literal1() (interface{}, error) {
stack := p.vstack[len(p.vstack)-1]
_ = stack
return p.cur.onUint64Literal1()
}
var (
// errNoRule is returned when the grammar to parse has no rule.
errNoRule = errors.New("grammar has no rule")
// errInvalidEntrypoint is returned when the specified entrypoint rule
// does not exit.
errInvalidEntrypoint = errors.New("invalid entrypoint")
// errInvalidEncoding is returned when the source is not properly
// utf8-encoded.
errInvalidEncoding = errors.New("invalid encoding")
// errMaxExprCnt is used to signal that the maximum number of
// expressions have been parsed.
errMaxExprCnt = errors.New("max number of expresssions parsed")
)
// Option is a function that can set an option on the parser. It returns
// the previous setting as an Option.
type Option func(*parser) Option
// MaxExpressions creates an Option to stop parsing after the provided
// number of expressions have been parsed, if the value is 0 then the parser will
// parse for as many steps as needed (possibly an infinite number).
//
// The default for maxExprCnt is 0.
func MaxExpressions(maxExprCnt uint64) Option {
return func(p *parser) Option {
oldMaxExprCnt := p.maxExprCnt
p.maxExprCnt = maxExprCnt
return MaxExpressions(oldMaxExprCnt)
}
}
// Entrypoint creates an Option to set the rule name to use as entrypoint.
// The rule name must have been specified in the -alternate-entrypoints
// if generating the parser with the -optimize-grammar flag, otherwise
// it may have been optimized out. Passing an empty string sets the
// entrypoint to the first rule in the grammar.
//
// The default is to start parsing at the first rule in the grammar.
func Entrypoint(ruleName string) Option {
return func(p *parser) Option {
oldEntrypoint := p.entrypoint
p.entrypoint = ruleName
if ruleName == "" {
p.entrypoint = g.rules[0].name
}
return Entrypoint(oldEntrypoint)
}
}
// Statistics adds a user provided Stats struct to the parser to allow
// the user to process the results after the parsing has finished.
// Also the key for the "no match" counter is set.
//
// Example usage:
//
// input := "input"
// stats := Stats{}
// _, err := Parse("input-file", []byte(input), Statistics(&stats, "no match"))
// if err != nil {
// log.Panicln(err)
// }
// b, err := json.MarshalIndent(stats.ChoiceAltCnt, "", " ")
// if err != nil {
// log.Panicln(err)
// }
// fmt.Println(string(b))
//
func Statistics(stats *Stats, choiceNoMatch string) Option {
return func(p *parser) Option {
oldStats := p.Stats
p.Stats = stats
oldChoiceNoMatch := p.choiceNoMatch
p.choiceNoMatch = choiceNoMatch
if p.Stats.ChoiceAltCnt == nil {
p.Stats.ChoiceAltCnt = make(map[string]map[string]int)
}
return Statistics(oldStats, oldChoiceNoMatch)
}
}
// Debug creates an Option to set the debug flag to b. When set to true,
// debugging information is printed to stdout while parsing.
//
// The default is false.
func Debug(b bool) Option {
return func(p *parser) Option {
old := p.debug
p.debug = b
return Debug(old)
}
}
// Memoize creates an Option to set the memoize flag to b. When set to true,
// the parser will cache all results so each expression is evaluated only
// once. This guarantees linear parsing time even for pathological cases,
// at the expense of more memory and slower times for typical cases.
//
// The default is false.
func Memoize(b bool) Option {
return func(p *parser) Option {
old := p.memoize
p.memoize = b
return Memoize(old)
}
}
// AllowInvalidUTF8 creates an Option to allow invalid UTF-8 bytes.
// Every invalid UTF-8 byte is treated as a utf8.RuneError (U+FFFD)
// by character class matchers and is matched by the any matcher.
// The returned matched value, c.text and c.offset are NOT affected.
//
// The default is false.
func AllowInvalidUTF8(b bool) Option {
return func(p *parser) Option {
old := p.allowInvalidUTF8
p.allowInvalidUTF8 = b
return AllowInvalidUTF8(old)
}
}
// Recover creates an Option to set the recover flag to b. When set to
// true, this causes the parser to recover from panics and convert it
// to an error. Setting it to false can be useful while debugging to
// access the full stack trace.
//
// The default is true.
func Recover(b bool) Option {
return func(p *parser) Option {
old := p.recover
p.recover = b
return Recover(old)
}
}
// GlobalStore creates an Option to set a key to a certain value in
// the globalStore.
func GlobalStore(key string, value interface{}) Option {
return func(p *parser) Option {
old := p.cur.globalStore[key]
p.cur.globalStore[key] = value
return GlobalStore(key, old)
}
}
// InitState creates an Option to set a key to a certain value in
// the global "state" store.
func InitState(key string, value interface{}) Option {
return func(p *parser) Option {
old := p.cur.state[key]
p.cur.state[key] = value
return InitState(key, old)
}
}
// ParseFile parses the file identified by filename.
func ParseFile(filename string, opts ...Option) (i interface{}, err error) {
f, err := os.Open(filename)
if err != nil {
return nil, err
}
defer func() {
if closeErr := f.Close(); closeErr != nil {
err = closeErr
}
}()
return ParseReader(filename, f, opts...)
}
// ParseReader parses the data from r using filename as information in the
// error messages.
func ParseReader(filename string, r io.Reader, opts ...Option) (interface{}, error) {
b, err := ioutil.ReadAll(r)
if err != nil {
return nil, err
}
return Parse(filename, b, opts...)
}
// Parse parses the data from b using filename as information in the
// error messages.
func Parse(filename string, b []byte, opts ...Option) (interface{}, error) {
return newParser(filename, b, opts...).parse(g)
}
// position records a position in the text.
type position struct {
line, col, offset int
}
func (p position) String() string {
return strconv.Itoa(p.line) + ":" + strconv.Itoa(p.col) + " [" + strconv.Itoa(p.offset) + "]"
}
// savepoint stores all state required to go back to this point in the
// parser.
type savepoint struct {
position
rn rune
w int
}
type current struct {
pos position // start position of the match
text []byte // raw text of the match
// state is a store for arbitrary key,value pairs that the user wants to be
// tied to the backtracking of the parser.
// This is always rolled back if a parsing rule fails.
state storeDict
// globalStore is a general store for the user to store arbitrary key-value
// pairs that they need to manage and that they do not want tied to the
// backtracking of the parser. This is only modified by the user and never
// rolled back by the parser. It is always up to the user to keep this in a
// consistent state.
globalStore storeDict
}
type storeDict map[string]interface{}
// the AST types...
type grammar struct {
pos position
rules []*rule
}
type rule struct {
pos position
name string
displayName string
expr interface{}
}
type choiceExpr struct {
pos position
alternatives []interface{}
}
type actionExpr struct {
pos position
expr interface{}
run func(*parser) (interface{}, error)
}
type recoveryExpr struct {
pos position
expr interface{}
recoverExpr interface{}
failureLabel []string
}
type seqExpr struct {
pos position
exprs []interface{}
}
type throwExpr struct {
pos position
label string
}
type labeledExpr struct {
pos position
label string
expr interface{}
}
type expr struct {
pos position
expr interface{}
}
type andExpr expr
type notExpr expr
type zeroOrOneExpr expr
type zeroOrMoreExpr expr
type oneOrMoreExpr expr
type ruleRefExpr struct {
pos position
name string
}
type stateCodeExpr struct {
pos position
run func(*parser) error
}
type andCodeExpr struct {
pos position
run func(*parser) (bool, error)
}
type notCodeExpr struct {
pos position
run func(*parser) (bool, error)
}
type litMatcher struct {
pos position
val string
ignoreCase bool
want string
}
type charClassMatcher struct {
pos position
val string
basicLatinChars [128]bool
chars []rune
ranges []rune
classes []*unicode.RangeTable
ignoreCase bool
inverted bool
}
type anyMatcher position
// errList cumulates the errors found by the parser.
type errList []error
func (e *errList) add(err error) {
*e = append(*e, err)
}
func (e errList) err() error {
if len(e) == 0 {
return nil
}
e.dedupe()
return e
}
func (e *errList) dedupe() {
var cleaned []error
set := make(map[string]bool)
for _, err := range *e {
if msg := err.Error(); !set[msg] {
set[msg] = true
cleaned = append(cleaned, err)
}
}
*e = cleaned
}
func (e errList) Error() string {
switch len(e) {
case 0:
return ""
case 1:
return e[0].Error()
default:
var buf bytes.Buffer
for i, err := range e {
if i > 0 {
buf.WriteRune('\n')
}
buf.WriteString(err.Error())
}
return buf.String()
}
}
// parserError wraps an error with a prefix indicating the rule in which
// the error occurred. The original error is stored in the Inner field.
type parserError struct {
Inner error
pos position
prefix string
expected []string
}
// Error returns the error message.
func (p *parserError) Error() string {
return p.prefix + ": " + p.Inner.Error()
}
// newParser creates a parser with the specified input source and options.
func newParser(filename string, b []byte, opts ...Option) *parser {
stats := Stats{
ChoiceAltCnt: make(map[string]map[string]int),
}
p := &parser{
filename: filename,
errs: new(errList),
data: b,
pt: savepoint{position: position{line: 1}},
recover: true,
cur: current{
state: make(storeDict),
globalStore: make(storeDict),
},
maxFailPos: position{col: 1, line: 1},
maxFailExpected: make([]string, 0, 20),
Stats: &stats,
// start rule is rule [0] unless an alternate entrypoint is specified
entrypoint: g.rules[0].name,
}
p.setOptions(opts)
if p.maxExprCnt == 0 {
p.maxExprCnt = math.MaxUint64
}
return p
}
// setOptions applies the options to the parser.
func (p *parser) setOptions(opts []Option) {
for _, opt := range opts {
opt(p)
}
}
type resultTuple struct {
v interface{}
b bool
end savepoint
}
const choiceNoMatch = -1
// Stats stores some statistics, gathered during parsing
type Stats struct {
// ExprCnt counts the number of expressions processed during parsing
// This value is compared to the maximum number of expressions allowed
// (set by the MaxExpressions option).
ExprCnt uint64
// ChoiceAltCnt is used to count for each ordered choice expression,
// which alternative is used how may times.
// These numbers allow to optimize the order of the ordered choice expression
// to increase the performance of the parser
//
// The outer key of ChoiceAltCnt is composed of the name of the rule as well
// as the line and the column of the ordered choice.
// The inner key of ChoiceAltCnt is the number (one-based) of the matching alternative.
// For each alternative the number of matches are counted. If an ordered choice does not
// match, a special counter is incremented. The name of this counter is set with
// the parser option Statistics.
// For an alternative to be included in ChoiceAltCnt, it has to match at least once.
ChoiceAltCnt map[string]map[string]int
}
type parser struct {
filename string
pt savepoint
cur current
data []byte
errs *errList
depth int
recover bool
debug bool
memoize bool
// memoization table for the packrat algorithm:
// map[offset in source] map[expression or rule] {value, match}
memo map[int]map[interface{}]resultTuple
// rules table, maps the rule identifier to the rule node
rules map[string]*rule
// variables stack, map of label to value
vstack []map[string]interface{}
// rule stack, allows identification of the current rule in errors
rstack []*rule
// parse fail
maxFailPos position
maxFailExpected []string
maxFailInvertExpected bool
// max number of expressions to be parsed
maxExprCnt uint64
// entrypoint for the parser
entrypoint string
allowInvalidUTF8 bool
*Stats
choiceNoMatch string
// recovery expression stack, keeps track of the currently available recovery expression, these are traversed in reverse
recoveryStack []map[string]interface{}
}
// push a variable set on the vstack.
func (p *parser) pushV() {
if cap(p.vstack) == len(p.vstack) {
// create new empty slot in the stack
p.vstack = append(p.vstack, nil)
} else {
// slice to 1 more
p.vstack = p.vstack[:len(p.vstack)+1]
}
// get the last args set
m := p.vstack[len(p.vstack)-1]
if m != nil && len(m) == 0 {
// empty map, all good
return
}
m = make(map[string]interface{})
p.vstack[len(p.vstack)-1] = m
}
// pop a variable set from the vstack.
func (p *parser) popV() {
// if the map is not empty, clear it
m := p.vstack[len(p.vstack)-1]
if len(m) > 0 {
// GC that map
p.vstack[len(p.vstack)-1] = nil
}
p.vstack = p.vstack[:len(p.vstack)-1]
}
// push a recovery expression with its labels to the recoveryStack
func (p *parser) pushRecovery(labels []string, expr interface{}) {
if cap(p.recoveryStack) == len(p.recoveryStack) {
// create new empty slot in the stack
p.recoveryStack = append(p.recoveryStack, nil)
} else {
// slice to 1 more
p.recoveryStack = p.recoveryStack[:len(p.recoveryStack)+1]
}
m := make(map[string]interface{}, len(labels))
for _, fl := range labels {
m[fl] = expr
}
p.recoveryStack[len(p.recoveryStack)-1] = m
}
// pop a recovery expression from the recoveryStack
func (p *parser) popRecovery() {
// GC that map
p.recoveryStack[len(p.recoveryStack)-1] = nil
p.recoveryStack = p.recoveryStack[:len(p.recoveryStack)-1]
}
func (p *parser) print(prefix, s string) string {
if !p.debug {
return s
}
fmt.Printf("%s %d:%d:%d: %s [%#U]\n",
prefix, p.pt.line, p.pt.col, p.pt.offset, s, p.pt.rn)
return s
}
func (p *parser) in(s string) string {
p.depth++
return p.print(strings.Repeat(" ", p.depth)+">", s)
}
func (p *parser) out(s string) string {
p.depth--
return p.print(strings.Repeat(" ", p.depth)+"<", s)
}
func (p *parser) addErr(err error) {
p.addErrAt(err, p.pt.position, []string{})
}
func (p *parser) addErrAt(err error, pos position, expected []string) {
var buf bytes.Buffer
if p.filename != "" {
buf.WriteString(p.filename)
}
if buf.Len() > 0 {
buf.WriteString(":")
}
buf.WriteString(fmt.Sprintf("%d:%d (%d)", pos.line, pos.col, pos.offset))
if len(p.rstack) > 0 {
if buf.Len() > 0 {
buf.WriteString(": ")
}
rule := p.rstack[len(p.rstack)-1]
if rule.displayName != "" {
buf.WriteString("rule " + rule.displayName)
} else {
buf.WriteString("rule " + rule.name)
}
}
pe := &parserError{Inner: err, pos: pos, prefix: buf.String(), expected: expected}
p.errs.add(pe)
}
func (p *parser) failAt(fail bool, pos position, want string) {
// process fail if parsing fails and not inverted or parsing succeeds and invert is set
if fail == p.maxFailInvertExpected {
if pos.offset < p.maxFailPos.offset {
return
}
if pos.offset > p.maxFailPos.offset {
p.maxFailPos = pos
p.maxFailExpected = p.maxFailExpected[:0]
}
if p.maxFailInvertExpected {
want = "!" + want
}
p.maxFailExpected = append(p.maxFailExpected, want)
}
}
// read advances the parser to the next rune.
func (p *parser) read() {
p.pt.offset += p.pt.w
rn, n := utf8.DecodeRune(p.data[p.pt.offset:])
p.pt.rn = rn
p.pt.w = n
p.pt.col++
if rn == '\n' {
p.pt.line++
p.pt.col = 0
}
if rn == utf8.RuneError && n == 1 { // see utf8.DecodeRune
if !p.allowInvalidUTF8 {
p.addErr(errInvalidEncoding)
}
}
}
// restore parser position to the savepoint pt.
func (p *parser) restore(pt savepoint) {
if p.debug {
defer p.out(p.in("restore"))
}
if pt.offset == p.pt.offset {
return
}
p.pt = pt
}
// Cloner is implemented by any value that has a Clone method, which returns a
// copy of the value. This is mainly used for types which are not passed by
// value (e.g map, slice, chan) or structs that contain such types.
//
// This is used in conjunction with the global state feature to create proper
// copies of the state to allow the parser to properly restore the state in
// the case of backtracking.
type Cloner interface {
Clone() interface{}
}
var statePool = &sync.Pool{
New: func() interface{} { return make(storeDict) },
}
func (sd storeDict) Discard() {
for k := range sd {
delete(sd, k)
}
statePool.Put(sd)
}
// clone and return parser current state.
func (p *parser) cloneState() storeDict {
if p.debug {
defer p.out(p.in("cloneState"))
}
state := statePool.Get().(storeDict)
for k, v := range p.cur.state {
if c, ok := v.(Cloner); ok {
state[k] = c.Clone()
} else {
state[k] = v
}
}
return state
}
// restore parser current state to the state storeDict.
// every restoreState should applied only one time for every cloned state
func (p *parser) restoreState(state storeDict) {
if p.debug {
defer p.out(p.in("restoreState"))
}
p.cur.state.Discard()
p.cur.state = state
}
// get the slice of bytes from the savepoint start to the current position.
func (p *parser) sliceFrom(start savepoint) []byte {
return p.data[start.position.offset:p.pt.position.offset]
}
func (p *parser) getMemoized(node interface{}) (resultTuple, bool) {
if len(p.memo) == 0 {
return resultTuple{}, false
}
m := p.memo[p.pt.offset]
if len(m) == 0 {
return resultTuple{}, false
}
res, ok := m[node]
return res, ok
}
func (p *parser) setMemoized(pt savepoint, node interface{}, tuple resultTuple) {
if p.memo == nil {
p.memo = make(map[int]map[interface{}]resultTuple)
}
m := p.memo[pt.offset]
if m == nil {
m = make(map[interface{}]resultTuple)
p.memo[pt.offset] = m
}
m[node] = tuple
}
func (p *parser) buildRulesTable(g *grammar) {
p.rules = make(map[string]*rule, len(g.rules))
for _, r := range g.rules {
p.rules[r.name] = r
}
}
func (p *parser) parse(g *grammar) (val interface{}, err error) {
if len(g.rules) == 0 {
p.addErr(errNoRule)
return nil, p.errs.err()
}
// TODO : not super critical but this could be generated
p.buildRulesTable(g)
if p.recover {
// panic can be used in action code to stop parsing immediately
// and return the panic as an error.
defer func() {
if e := recover(); e != nil {
if p.debug {
defer p.out(p.in("panic handler"))
}
val = nil
switch e := e.(type) {
case error:
p.addErr(e)
default:
p.addErr(fmt.Errorf("%v", e))
}
err = p.errs.err()
}
}()
}
startRule, ok := p.rules[p.entrypoint]
if !ok {
p.addErr(errInvalidEntrypoint)
return nil, p.errs.err()
}
p.read() // advance to first rune
val, ok = p.parseRule(startRule)
if !ok {
if len(*p.errs) == 0 {
// If parsing fails, but no errors have been recorded, the expected values
// for the farthest parser position are returned as error.
maxFailExpectedMap := make(map[string]struct{}, len(p.maxFailExpected))
for _, v := range p.maxFailExpected {
maxFailExpectedMap[v] = struct{}{}
}
expected := make([]string, 0, len(maxFailExpectedMap))
eof := false
if _, ok := maxFailExpectedMap["!."]; ok {
delete(maxFailExpectedMap, "!.")
eof = true
}
for k := range maxFailExpectedMap {
expected = append(expected, k)
}
sort.Strings(expected)
if eof {
expected = append(expected, "EOF")
}
p.addErrAt(errors.New("no match found, expected: "+listJoin(expected, ", ", "or")), p.maxFailPos, expected)
}
return nil, p.errs.err()
}
return val, p.errs.err()
}
func listJoin(list []string, sep string, lastSep string) string {
switch len(list) {
case 0:
return ""
case 1:
return list[0]
default:
return strings.Join(list[:len(list)-1], sep) + " " + lastSep + " " + list[len(list)-1]
}
}
func (p *parser) parseRule(rule *rule) (interface{}, bool) {
if p.debug {
defer p.out(p.in("parseRule " + rule.name))
}
if p.memoize {
res, ok := p.getMemoized(rule)
if ok {
p.restore(res.end)
return res.v, res.b
}
}
start := p.pt
p.rstack = append(p.rstack, rule)
p.pushV()
val, ok := p.parseExpr(rule.expr)
p.popV()
p.rstack = p.rstack[:len(p.rstack)-1]
if ok && p.debug {
p.print(strings.Repeat(" ", p.depth)+"MATCH", string(p.sliceFrom(start)))
}
if p.memoize {
p.setMemoized(start, rule, resultTuple{val, ok, p.pt})
}
return val, ok
}
func (p *parser) parseExpr(expr interface{}) (interface{}, bool) {
var pt savepoint
if p.memoize {
res, ok := p.getMemoized(expr)
if ok {
p.restore(res.end)
return res.v, res.b
}
pt = p.pt
}
p.ExprCnt++
if p.ExprCnt > p.maxExprCnt {
panic(errMaxExprCnt)
}
var val interface{}
var ok bool
switch expr := expr.(type) {
case *actionExpr:
val, ok = p.parseActionExpr(expr)
case *andCodeExpr:
val, ok = p.parseAndCodeExpr(expr)
case *andExpr:
val, ok = p.parseAndExpr(expr)
case *anyMatcher:
val, ok = p.parseAnyMatcher(expr)
case *charClassMatcher:
val, ok = p.parseCharClassMatcher(expr)
case *choiceExpr:
val, ok = p.parseChoiceExpr(expr)
case *labeledExpr:
val, ok = p.parseLabeledExpr(expr)
case *litMatcher:
val, ok = p.parseLitMatcher(expr)
case *notCodeExpr:
val, ok = p.parseNotCodeExpr(expr)
case *notExpr:
val, ok = p.parseNotExpr(expr)
case *oneOrMoreExpr:
val, ok = p.parseOneOrMoreExpr(expr)
case *recoveryExpr:
val, ok = p.parseRecoveryExpr(expr)
case *ruleRefExpr:
val, ok = p.parseRuleRefExpr(expr)
case *seqExpr:
val, ok = p.parseSeqExpr(expr)
case *stateCodeExpr:
val, ok = p.parseStateCodeExpr(expr)
case *throwExpr:
val, ok = p.parseThrowExpr(expr)
case *zeroOrMoreExpr:
val, ok = p.parseZeroOrMoreExpr(expr)
case *zeroOrOneExpr:
val, ok = p.parseZeroOrOneExpr(expr)
default:
panic(fmt.Sprintf("unknown expression type %T", expr))
}
if p.memoize {
p.setMemoized(pt, expr, resultTuple{val, ok, p.pt})
}
return val, ok
}
func (p *parser) parseActionExpr(act *actionExpr) (interface{}, bool) {
if p.debug {
defer p.out(p.in("parseActionExpr"))
}
start := p.pt
val, ok := p.parseExpr(act.expr)
if ok {
p.cur.pos = start.position
p.cur.text = p.sliceFrom(start)
state := p.cloneState()
actVal, err := act.run(p)
if err != nil {
p.addErrAt(err, start.position, []string{})
}
p.restoreState(state)
val = actVal
}
if ok && p.debug {
p.print(strings.Repeat(" ", p.depth)+"MATCH", string(p.sliceFrom(start)))
}
return val, ok
}
func (p *parser) parseAndCodeExpr(and *andCodeExpr) (interface{}, bool) {
if p.debug {
defer p.out(p.in("parseAndCodeExpr"))
}
state := p.cloneState()
ok, err := and.run(p)
if err != nil {
p.addErr(err)
}
p.restoreState(state)
return nil, ok
}
func (p *parser) parseAndExpr(and *andExpr) (interface{}, bool) {
if p.debug {
defer p.out(p.in("parseAndExpr"))
}
pt := p.pt
state := p.cloneState()
p.pushV()
_, ok := p.parseExpr(and.expr)
p.popV()
p.restoreState(state)
p.restore(pt)
return nil, ok
}
func (p *parser) parseAnyMatcher(any *anyMatcher) (interface{}, bool) {
if p.debug {
defer p.out(p.in("parseAnyMatcher"))
}
if p.pt.rn == utf8.RuneError && p.pt.w == 0 {
// EOF - see utf8.DecodeRune
p.failAt(false, p.pt.position, ".")
return nil, false
}
start := p.pt
p.read()
p.failAt(true, start.position, ".")
return p.sliceFrom(start), true
}
func (p *parser) parseCharClassMatcher(chr *charClassMatcher) (interface{}, bool) {
if p.debug {
defer p.out(p.in("parseCharClassMatcher"))
}
cur := p.pt.rn
start := p.pt
// can't match EOF
if cur == utf8.RuneError && p.pt.w == 0 { // see utf8.DecodeRune
p.failAt(false, start.position, chr.val)
return nil, false
}
if chr.ignoreCase {
cur = unicode.ToLower(cur)
}
// try to match in the list of available chars
for _, rn := range chr.chars {
if rn == cur {
if chr.inverted {
p.failAt(false, start.position, chr.val)
return nil, false
}
p.read()
p.failAt(true, start.position, chr.val)
return p.sliceFrom(start), true
}
}
// try to match in the list of ranges
for i := 0; i < len(chr.ranges); i += 2 {
if cur >= chr.ranges[i] && cur <= chr.ranges[i+1] {
if chr.inverted {
p.failAt(false, start.position, chr.val)
return nil, false
}
p.read()
p.failAt(true, start.position, chr.val)
return p.sliceFrom(start), true
}
}
// try to match in the list of Unicode classes
for _, cl := range chr.classes {
if unicode.Is(cl, cur) {
if chr.inverted {
p.failAt(false, start.position, chr.val)
return nil, false
}
p.read()
p.failAt(true, start.position, chr.val)
return p.sliceFrom(start), true
}
}
if chr.inverted {
p.read()
p.failAt(true, start.position, chr.val)
return p.sliceFrom(start), true
}
p.failAt(false, start.position, chr.val)
return nil, false
}
func (p *parser) incChoiceAltCnt(ch *choiceExpr, altI int) {
choiceIdent := fmt.Sprintf("%s %d:%d", p.rstack[len(p.rstack)-1].name, ch.pos.line, ch.pos.col)
m := p.ChoiceAltCnt[choiceIdent]
if m == nil {
m = make(map[string]int)
p.ChoiceAltCnt[choiceIdent] = m
}
// We increment altI by 1, so the keys do not start at 0
alt := strconv.Itoa(altI + 1)
if altI == choiceNoMatch {
alt = p.choiceNoMatch
}
m[alt]++
}
func (p *parser) parseChoiceExpr(ch *choiceExpr) (interface{}, bool) {
if p.debug {
defer p.out(p.in("parseChoiceExpr"))
}
for altI, alt := range ch.alternatives {
// dummy assignment to prevent compile error if optimized
_ = altI
state := p.cloneState()
p.pushV()
val, ok := p.parseExpr(alt)
p.popV()
if ok {
p.incChoiceAltCnt(ch, altI)
return val, ok
}
p.restoreState(state)
}
p.incChoiceAltCnt(ch, choiceNoMatch)
return nil, false
}
func (p *parser) parseLabeledExpr(lab *labeledExpr) (interface{}, bool) {
if p.debug {
defer p.out(p.in("parseLabeledExpr"))
}
p.pushV()
val, ok := p.parseExpr(lab.expr)
p.popV()
if ok && lab.label != "" {
m := p.vstack[len(p.vstack)-1]
m[lab.label] = val
}
return val, ok
}
func (p *parser) parseLitMatcher(lit *litMatcher) (interface{}, bool) {
if p.debug {
defer p.out(p.in("parseLitMatcher"))
}
start := p.pt
for _, want := range lit.val {
cur := p.pt.rn
if lit.ignoreCase {
cur = unicode.ToLower(cur)
}
if cur != want {
p.failAt(false, start.position, lit.want)
p.restore(start)
return nil, false
}
p.read()
}
p.failAt(true, start.position, lit.want)
return p.sliceFrom(start), true
}
func (p *parser) parseNotCodeExpr(not *notCodeExpr) (interface{}, bool) {
if p.debug {
defer p.out(p.in("parseNotCodeExpr"))
}
state := p.cloneState()
ok, err := not.run(p)
if err != nil {
p.addErr(err)
}
p.restoreState(state)
return nil, !ok
}
func (p *parser) parseNotExpr(not *notExpr) (interface{}, bool) {
if p.debug {
defer p.out(p.in("parseNotExpr"))
}
pt := p.pt
state := p.cloneState()
p.pushV()
p.maxFailInvertExpected = !p.maxFailInvertExpected
_, ok := p.parseExpr(not.expr)
p.maxFailInvertExpected = !p.maxFailInvertExpected
p.popV()
p.restoreState(state)
p.restore(pt)
return nil, !ok
}
func (p *parser) parseOneOrMoreExpr(expr *oneOrMoreExpr) (interface{}, bool) {
if p.debug {
defer p.out(p.in("parseOneOrMoreExpr"))
}
var vals []interface{}
for {
p.pushV()
val, ok := p.parseExpr(expr.expr)
p.popV()
if !ok {
if len(vals) == 0 {
// did not match once, no match
return nil, false
}
return vals, true
}
vals = append(vals, val)
}
}
func (p *parser) parseRecoveryExpr(recover *recoveryExpr) (interface{}, bool) {
if p.debug {
defer p.out(p.in("parseRecoveryExpr (" + strings.Join(recover.failureLabel, ",") + ")"))
}
p.pushRecovery(recover.failureLabel, recover.recoverExpr)
val, ok := p.parseExpr(recover.expr)
p.popRecovery()
return val, ok
}
func (p *parser) parseRuleRefExpr(ref *ruleRefExpr) (interface{}, bool) {
if p.debug {
defer p.out(p.in("parseRuleRefExpr " + ref.name))
}
if ref.name == "" {
panic(fmt.Sprintf("%s: invalid rule: missing name", ref.pos))
}
rule := p.rules[ref.name]
if rule == nil {
p.addErr(fmt.Errorf("undefined rule: %s", ref.name))
return nil, false
}
return p.parseRule(rule)
}
func (p *parser) parseSeqExpr(seq *seqExpr) (interface{}, bool) {
if p.debug {
defer p.out(p.in("parseSeqExpr"))
}
vals := make([]interface{}, 0, len(seq.exprs))
pt := p.pt
state := p.cloneState()
for _, expr := range seq.exprs {
val, ok := p.parseExpr(expr)
if !ok {
p.restoreState(state)
p.restore(pt)
return nil, false
}
vals = append(vals, val)
}
return vals, true
}
func (p *parser) parseStateCodeExpr(state *stateCodeExpr) (interface{}, bool) {
if p.debug {
defer p.out(p.in("parseStateCodeExpr"))
}
err := state.run(p)
if err != nil {
p.addErr(err)
}
return nil, true
}
func (p *parser) parseThrowExpr(expr *throwExpr) (interface{}, bool) {
if p.debug {
defer p.out(p.in("parseThrowExpr"))
}
for i := len(p.recoveryStack) - 1; i >= 0; i-- {
if recoverExpr, ok := p.recoveryStack[i][expr.label]; ok {
if val, ok := p.parseExpr(recoverExpr); ok {
return val, ok
}
}
}
return nil, false
}
func (p *parser) parseZeroOrMoreExpr(expr *zeroOrMoreExpr) (interface{}, bool) {
if p.debug {
defer p.out(p.in("parseZeroOrMoreExpr"))
}
var vals []interface{}
for {
p.pushV()
val, ok := p.parseExpr(expr.expr)
p.popV()
if !ok {
return vals, true
}
vals = append(vals, val)
}
}
func (p *parser) parseZeroOrOneExpr(expr *zeroOrOneExpr) (interface{}, bool) {
if p.debug {
defer p.out(p.in("parseZeroOrOneExpr"))
}
p.pushV()
val, _ := p.parseExpr(expr.expr)
p.popV()
// whether it matched or not, consider it a match
return val, true
}
addchain-0.4.0/acc/parse/parse.go 0000664 0000000 0000000 00000001464 15143052566 0016563 0 ustar 00root root 0000000 0000000 // Package parse implements a parser for acc programs.
package parse
import (
"io"
"strings"
"github.com/mmcloughlin/addchain/acc/ast"
"github.com/mmcloughlin/addchain/acc/parse/internal/parser"
)
//go:generate pigeon -o internal/parser/zparser.go acc.peg
// File parses filename.
func File(filename string) (*ast.Chain, error) {
return cast(parser.ParseFile(filename))
}
// Reader parses the data from r using filename as information in
// error messages.
func Reader(filename string, r io.Reader) (*ast.Chain, error) {
return cast(parser.ParseReader(filename, r))
}
// String parses s.
func String(s string) (*ast.Chain, error) {
return Reader("string", strings.NewReader(s))
}
func cast(i interface{}, err error) (*ast.Chain, error) {
if err != nil {
return nil, err
}
return i.(*ast.Chain), nil
}
addchain-0.4.0/acc/parse/parse_test.go 0000664 0000000 0000000 00000005406 15143052566 0017622 0 ustar 00root root 0000000 0000000 package parse
import (
"reflect"
"testing"
"github.com/mmcloughlin/addchain/acc/ast"
)
func TestOperands(t *testing.T) {
exprs := map[string]ast.Expr{
"1": ast.Operand(0),
"[23]": ast.Operand(23),
"[0x2a]": ast.Operand(0x2a),
"[0644]": ast.Operand(0o644),
"(1)": ast.Operand(0),
"( [3] )": ast.Operand(3),
"_101": ast.Identifier("_101"),
"x5": ast.Identifier("x5"),
"( x5)": ast.Identifier("x5"),
}
for expr, idx := range exprs {
AssertParseResult(t, expr, idx)
AssertParseResult(t, expr+"\n", idx)
}
}
func TestExpressions(t *testing.T) {
cases := []struct {
Source string
Expect ast.Expr
}{
{
Source: "1 + 1",
Expect: ast.Add{X: ast.Operand(0), Y: ast.Operand(0)},
},
{
Source: "1 add 1",
Expect: ast.Add{X: ast.Operand(0), Y: ast.Operand(0)},
},
{
Source: "1 + 1 + 1",
Expect: ast.Add{
X: ast.Add{X: ast.Operand(0), Y: ast.Operand(0)},
Y: ast.Operand(0),
},
},
{
Source: "1 add 1 add 1",
Expect: ast.Add{
X: ast.Add{X: ast.Operand(0), Y: ast.Operand(0)},
Y: ast.Operand(0),
},
},
{
Source: "1 << 5",
Expect: ast.Shift{X: ast.Operand(0), S: 5},
},
{
Source: "[3] shl 5 add 1",
Expect: ast.Add{
X: ast.Shift{X: ast.Operand(3), S: 5},
Y: ast.Operand(0),
},
},
{
Source: "[3] << 5 + [6] << 9",
Expect: ast.Add{
X: ast.Shift{X: ast.Operand(3), S: 5},
Y: ast.Shift{X: ast.Operand(6), S: 9},
},
},
{
Source: "([3] + [8]) << 2",
Expect: ast.Shift{
X: ast.Add{X: ast.Operand(3), Y: ast.Operand(8)},
S: 2,
},
},
{
Source: "2 * [3]",
Expect: ast.Double{
X: ast.Operand(3),
},
},
{
Source: "dbl [3] add [5] << 3",
Expect: ast.Add{
X: ast.Double{X: ast.Operand(3)},
Y: ast.Shift{X: ast.Operand(5), S: 3},
},
},
}
for _, c := range cases {
AssertParseResult(t, c.Source, c.Expect)
}
}
func TestChains(t *testing.T) {
cases := []struct {
Source string
Expect *ast.Chain
}{
{
Source: "x = 1 + 1\nreturn x<<3",
Expect: &ast.Chain{
Statements: []ast.Statement{
{
Name: "x",
Expr: ast.Add{
X: ast.Operand(0),
Y: ast.Operand(0),
},
},
{
Expr: ast.Shift{
X: ast.Identifier("x"),
S: 3,
},
},
},
},
},
}
for _, c := range cases {
AssertParse(t, c.Source, c.Expect)
}
}
func AssertParseResult(t *testing.T, src string, expect ast.Expr) {
t.Helper()
AssertParse(t, src, &ast.Chain{
Statements: []ast.Statement{{Expr: expect}},
})
}
func AssertParse(t *testing.T, src string, expect *ast.Chain) {
t.Helper()
t.Logf("expr=%q", src)
got, err := String(src)
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(expect, got) {
t.Fatalf("got %#v; expected %#v", got, expect)
}
}
addchain-0.4.0/acc/pass/ 0000775 0000000 0000000 00000000000 15143052566 0014751 5 ustar 00root root 0000000 0000000 addchain-0.4.0/acc/pass/alloc.go 0000664 0000000 0000000 00000004662 15143052566 0016402 0 ustar 00root root 0000000 0000000 package pass
import (
"fmt"
"github.com/mmcloughlin/addchain/acc/ir"
"github.com/mmcloughlin/addchain/internal/container/heap"
"github.com/mmcloughlin/addchain/internal/errutil"
)
// Allocator pass assigns a minimal number of temporary variables to execute a program.
type Allocator struct {
// Input is the name of the input variable. Note this is index 0, or the
// identity element of the addition chain.
Input string
// Output is the name to give to the final output of the addition chain. This
// variable may itself be used as a temporary during execution.
Output string
// Format defines how to format any temporary variables. This format string
// must accept one integer value. For example "t%d" would be a reasonable
// choice.
Format string
}
// Execute performs temporary variable allocation.
func (a Allocator) Execute(p *ir.Program) error {
// Canonicalize operands and delete all names.
if err := Exec(p, Func(CanonicalizeOperands), Func(ClearNames)); err != nil {
return err
}
// Initialize allocation. This maps operand index to variable index. The
// inidicies 0 and 1 are special, reserved for the input and output
// respectively. Any indicies above that are temporaries.
out := p.Output()
allocation := map[int]int{
0: 0,
out.Index: 1,
}
n := 2
// Keep a heap of available indicies. Initially none.
available := heap.NewMinInts()
// Process instructions in reverse.
for i := len(p.Instructions) - 1; i >= 0; i-- {
inst := p.Instructions[i]
// The output operand variable now becomes available.
v, ok := allocation[inst.Output.Index]
if !ok {
return errutil.AssertionFailure("output operand %d missing allocation", inst.Output.Index)
}
available.Push(v)
// Inputs may need variables, if they are not already live.
for _, input := range inst.Op.Inputs() {
_, ok := allocation[input.Index]
if ok {
continue
}
// If there's nothing available, we'll need one more temporary.
if available.Empty() {
available.Push(n)
n++
}
allocation[input.Index] = available.Pop()
}
}
// Record allocation.
for _, op := range p.Operands {
op.Identifier = a.name(allocation[op.Index])
}
temps := []string{}
for i := 2; i < n; i++ {
temps = append(temps, a.name(i))
}
p.Temporaries = temps
return nil
}
func (a Allocator) name(v int) string {
switch v {
case 0:
return a.Input
case 1:
return a.Output
default:
return fmt.Sprintf(a.Format, v-2)
}
}
addchain-0.4.0/acc/pass/alloc_test.go 0000664 0000000 0000000 00000003272 15143052566 0017435 0 ustar 00root root 0000000 0000000 package pass
import (
"reflect"
"strconv"
"testing"
"github.com/mmcloughlin/addchain/acc/ir"
)
func TestAllocator(t *testing.T) {
// Generate a program that will need n live variables.
n := 13
p := &ir.Program{}
// Create n indexes that will be used later.
for i := 1; i <= n; i++ {
p.AddInstruction(&ir.Instruction{
Output: ir.Index(i),
Op: ir.Add{
X: ir.One,
Y: ir.Index(i - 1),
},
})
}
// Consume the n indicies. This ensures we'll have n live variables at some
// point.
for i := n + 1; i <= 2*n; i++ {
p.AddInstruction(&ir.Instruction{
Output: ir.Index(i),
Op: ir.Add{
X: ir.Index(i - n),
Y: ir.Index(i - 1),
},
})
}
// Execute allocation pass.
t.Logf("pre:\n%s", p)
a := Allocator{
Input: "in",
Output: "out",
Format: "tmp%d",
}
if err := a.Execute(p); err != nil {
t.Fatal(err)
}
t.Logf("post:\n%s", p)
// Every operand should have a name.
for _, operand := range p.Operands {
if operand.Identifier == "" {
t.Errorf("operand %s does not have a name", operand)
}
}
// We expect to have n-1 temporaries. Note we do not expect n, since the output
// variable will be used as a temporary.
expect := make([]string, n-1)
for i := 0; i < n-1; i++ {
expect[i] = "tmp" + strconv.Itoa(i)
}
if !reflect.DeepEqual(expect, p.Temporaries) {
t.Fatalf("got temporaries %v; expect %v", p.Temporaries, expect)
}
// Confirm input and output variables are used.
if p.Operands[0].Identifier != a.Input {
t.Errorf("unexpected input name: got %q expect %q", p.Operands[0].Identifier, a.Input)
}
if p.Output().Identifier != a.Output {
t.Errorf("unexpected output name: got %q expect %q", p.Output().Identifier, a.Output)
}
}
addchain-0.4.0/acc/pass/eval.go 0000664 0000000 0000000 00000002116 15143052566 0016227 0 ustar 00root root 0000000 0000000 package pass
import (
"errors"
"github.com/mmcloughlin/addchain"
"github.com/mmcloughlin/addchain/acc/ir"
"github.com/mmcloughlin/addchain/internal/errutil"
)
// Compile generates the fully unrolled sequence of additions. The result is
// stored in the Program field.
func Compile(p *ir.Program) error {
if p.Program != nil {
return nil
}
p.Program = addchain.Program{}
for _, i := range p.Instructions {
var out int
var err error
switch op := i.Op.(type) {
case ir.Add:
out, err = p.Program.Add(op.X.Index, op.Y.Index)
case ir.Double:
out, err = p.Program.Double(op.X.Index)
case ir.Shift:
out, err = p.Program.Shift(op.X.Index, op.S)
default:
return errutil.UnexpectedType(op)
}
if err != nil {
return err
}
if out != i.Output.Index {
return errors.New("incorrect output index")
}
}
return nil
}
// Eval evaluates the program and places the result in the Chain field.
func Eval(p *ir.Program) error {
if p.Chain != nil {
return nil
}
if err := Compile(p); err != nil {
return err
}
p.Chain = p.Program.Evaluate()
return nil
}
addchain-0.4.0/acc/pass/naming.go 0000664 0000000 0000000 00000004552 15143052566 0016557 0 ustar 00root root 0000000 0000000 package pass
import (
"fmt"
"math/big"
"github.com/mmcloughlin/addchain/acc/ir"
"github.com/mmcloughlin/addchain/internal/bigint"
"github.com/mmcloughlin/addchain/internal/errutil"
)
// References:
//
// [curvechains] Brian Smith. The Most Efficient Known Addition Chains for Field Element and
// Scalar Inversion for the Most Popular and Most Unpopular Elliptic Curves. 2017.
// https://briansmith.org/ecc-inversion-addition-chains-01 (accessed June 30, 2019)
// Naming conventions described in [curvechains].
var (
NameByteValues = NameBinaryValues(8, "_%b")
NameXRuns = NameBinaryRuns("x%d")
)
// ClearNames deletes all operand names.
func ClearNames(p *ir.Program) error {
if err := CanonicalizeOperands(p); err != nil {
return err
}
for _, operand := range p.Operands {
operand.Identifier = ""
}
return nil
}
// NameBinaryValues assigns variable names to operands with values less than 2ᵏ.
// The identifier is determined from the format string, which should expect to
// take one *big.Int argument.
func NameBinaryValues(k int, format string) Interface {
return NameOperands(func(_ int, x *big.Int) string {
if x.BitLen() > k {
return ""
}
return fmt.Sprintf(format, x)
})
}
// NameBinaryRuns assigns variable names to operands with values of the form 2ⁿ
// - 1. The identifier is determined from the format string, which takes the
// length of the run as a parameter.
func NameBinaryRuns(format string) Interface {
return NameOperands(func(_ int, x *big.Int) string {
n := uint(x.BitLen())
if !bigint.Equal(x, bigint.Ones(n)) {
return ""
}
return fmt.Sprintf(format, n)
})
}
// NameOperands builds a pass that names operands according to the given scheme.
func NameOperands(name func(int, *big.Int) string) Interface {
return Func(func(p *ir.Program) error {
// We need canonical operands, and we need to know the chain values.
if err := Exec(p, Func(CanonicalizeOperands), Func(Eval)); err != nil {
return err
}
for _, operand := range p.Operands {
// Skip if it already has a name.
if operand.Identifier != "" {
continue
}
// Fetch referenced value.
idx := operand.Index
if idx >= len(p.Chain) {
return errutil.AssertionFailure("operand index %d out of bounds", idx)
}
x := p.Chain[idx]
// Set name.
operand.Identifier = name(idx, x)
}
return nil
})
}
addchain-0.4.0/acc/pass/naming_test.go 0000664 0000000 0000000 00000002036 15143052566 0017611 0 ustar 00root root 0000000 0000000 package pass
import (
"testing"
"github.com/mmcloughlin/addchain/acc/ir"
)
func TestNaming(t *testing.T) {
p := &ir.Program{
Instructions: []*ir.Instruction{
{
Output: ir.Index(1),
Op: ir.Double{
X: ir.Index(0),
},
},
{
Output: ir.Index(2),
Op: ir.Add{
X: ir.Index(0),
Y: ir.Index(1),
},
},
{
Output: ir.Index(4),
Op: ir.Shift{
X: ir.Index(2),
S: 2,
},
},
{
Output: ir.Index(5),
Op: ir.Add{
X: ir.Index(4),
Y: ir.Index(2),
},
},
},
}
// Name 3-bit values and runs.
n := Concat(
NameBinaryValues(3, "_%b"),
NameXRuns,
)
t.Logf("pre:\n%s", p)
if err := n.Execute(p); err != nil {
t.Fatal(err)
}
t.Logf("post:\n%s", p)
// Expected names.
expect := map[int]string{
0: "_1",
1: "_10",
2: "_11",
4: "", // 4-bit value that's not a run
5: "x4",
}
for idx, name := range expect {
got := p.Operands[idx].Identifier
if got != name {
t.Errorf("operand %d has name %s; expected %s", idx, got, name)
}
}
}
addchain-0.4.0/acc/pass/pass.go 0000664 0000000 0000000 00000005504 15143052566 0016252 0 ustar 00root root 0000000 0000000 // Package pass implements analysis and processing passes on acc programs.
package pass
import (
"fmt"
"github.com/mmcloughlin/addchain/acc/ir"
"github.com/mmcloughlin/addchain/internal/errutil"
)
// Interface for a processing pass.
type Interface interface {
Execute(*ir.Program) error
}
// Func adapts a function to the pass Interface.
type Func func(*ir.Program) error
// Execute calls p.
func (f Func) Execute(p *ir.Program) error {
return f(p)
}
// Concat returns a pass that executes the given passes in order, stopping on
// the first error.
func Concat(passes ...Interface) Interface {
return Func(func(p *ir.Program) error {
for _, pass := range passes {
if err := pass.Execute(p); err != nil {
return err
}
}
return nil
})
}
// Exec is a convenience for executing a list of passes on p.
func Exec(p *ir.Program, passes ...Interface) error {
return Concat(passes...).Execute(p)
}
// CanonicalizeOperands ensures there is only one Operand object for each
// operand index in the program. In particular, this ensures there are not
// conflicting names for the same index. Populates the Operands field of the
// program.
func CanonicalizeOperands(p *ir.Program) error {
if p.Operands != nil {
return nil
}
p.Operands = map[int]*ir.Operand{}
// First pass through determines canonical operand for each index.
for _, i := range p.Instructions {
for _, operand := range i.Operands() {
// Look for an existing operand object for this index.
existing, found := p.Operands[operand.Index]
if !found {
p.Operands[operand.Index] = operand
continue
}
if existing == operand {
continue
}
// They're different objects. Check for a name conflict.
if existing.Identifier != "" && operand.Identifier != "" && existing.Identifier != operand.Identifier {
return fmt.Errorf("identifier conflict: index %d named %q and %q", operand.Index, operand.Identifier, existing.Identifier)
}
if operand.Identifier != "" {
existing.Identifier = operand.Identifier
}
}
}
// Second pass through replaces all operands with the canonical version.
for _, i := range p.Instructions {
switch op := i.Op.(type) {
case ir.Add:
i.Op = ir.Add{
X: p.Operands[op.X.Index],
Y: p.Operands[op.Y.Index],
}
case ir.Double:
i.Op = ir.Double{
X: p.Operands[op.X.Index],
}
case ir.Shift:
i.Op = ir.Shift{
X: p.Operands[op.X.Index],
S: op.S,
}
default:
return errutil.UnexpectedType(op)
}
}
return nil
}
// ReadCounts computes how many times each index is read in the program. This
// populates the ReadCount field of the program.
func ReadCounts(p *ir.Program) error {
if p.ReadCount != nil {
return nil
}
p.ReadCount = map[int]int{}
for _, i := range p.Instructions {
for _, input := range i.Op.Inputs() {
p.ReadCount[input.Index]++
}
}
return nil
}
addchain-0.4.0/acc/pass/pass_test.go 0000664 0000000 0000000 00000004542 15143052566 0017312 0 ustar 00root root 0000000 0000000 package pass
import (
"reflect"
"testing"
"github.com/mmcloughlin/addchain/acc/ir"
"github.com/mmcloughlin/addchain/internal/assert"
)
func TestCanonicalizeOperands(t *testing.T) {
// Index 1 is referenced multiple times from various operand types. Only one of
// them has a name. Expect them to be replaced with a single version that has a
// name.
p := &ir.Program{
Instructions: []*ir.Instruction{
{
Output: ir.Index(1), // unnamed
Op: ir.Double{
X: ir.One,
},
},
{
Output: ir.Index(2),
Op: ir.Add{
X: ir.One,
Y: ir.NewOperand("a", 1), // named
},
},
{
Output: ir.Index(3),
Op: ir.Double{
X: ir.Index(1), // unnamed
},
},
{
Output: ir.Index(4),
Op: ir.Shift{
X: ir.Index(1), // unnamed
S: 1,
},
},
},
}
t.Logf("pre:\n%s", p)
err := CanonicalizeOperands(p)
if err != nil {
t.Fatal(err)
}
t.Logf("post:\n%s", p)
// Check all operands are canonical.
for _, i := range p.Instructions {
for _, operand := range i.Operands() {
if operand != p.Operands[operand.Index] {
t.Fatal("non canonical operand found")
}
}
}
// Check that the canonical version has a name.
if p.Operands[1].Identifier != "a" {
t.Fatal("operand 1 should have a name")
}
}
func TestCanonicalizeOperandsIdentifierConflict(t *testing.T) {
// Construct a program with two names for index 1.
p := &ir.Program{
Instructions: []*ir.Instruction{
{
Output: ir.NewOperand("a", 1),
Op: ir.Double{
X: ir.One,
},
},
{
Output: ir.NewOperand("c", 2),
Op: ir.Add{
X: ir.One,
Y: ir.NewOperand("b", 1),
},
},
},
}
err := CanonicalizeOperands(p)
assert.ErrorContains(t, err, "conflict")
}
func TestReadCounts(t *testing.T) {
p := &ir.Program{
Instructions: []*ir.Instruction{
{
Output: ir.Index(1),
Op: ir.Double{
X: ir.Index(0),
},
},
{
Output: ir.Index(2),
Op: ir.Add{
X: ir.Index(0),
Y: ir.Index(1),
},
},
{
Output: ir.Index(5),
Op: ir.Shift{
X: ir.Index(1),
S: 3,
},
},
{
Output: ir.Index(6),
Op: ir.Add{
X: ir.Index(0),
Y: ir.Index(5),
},
},
},
}
expect := map[int]int{
0: 3,
1: 2,
5: 1,
}
if err := ReadCounts(p); err != nil {
t.Fatal(p)
}
if !reflect.DeepEqual(expect, p.ReadCount) {
t.FailNow()
}
}
addchain-0.4.0/acc/pass/validation.go 0000664 0000000 0000000 00000001524 15143052566 0017434 0 ustar 00root root 0000000 0000000 package pass
import (
"fmt"
"github.com/mmcloughlin/addchain/acc/ir"
)
// Validate is a pass to sanity check an intermediate representation program.
var Validate = Func(CheckDanglingInputs)
// CheckDanglingInputs looks for program inputs that have no instruction
// outputting them. Note this can happen and still be technically correct. For
// example a shift instruction produces many intermediate results, and one of
// these can later be referenced. The resulting program is still correct, but
// undesirable.
func CheckDanglingInputs(p *ir.Program) error {
outputset := map[int]bool{0: true}
for _, i := range p.Instructions {
for _, input := range i.Op.Inputs() {
if !outputset[input.Index] {
return fmt.Errorf("no output instruction for input index %d", input.Index)
}
}
outputset[i.Output.Index] = true
}
return nil
}
addchain-0.4.0/acc/pass/validation_test.go 0000664 0000000 0000000 00000001036 15143052566 0020471 0 ustar 00root root 0000000 0000000 package pass
import (
"testing"
"github.com/mmcloughlin/addchain/acc/ir"
)
func TestCheckDanglingInputsError(t *testing.T) {
// Shift instruction followed by a reference to an intermediate result.
p := &ir.Program{
Instructions: []*ir.Instruction{
{
Output: ir.Index(3),
Op: ir.Shift{
X: ir.Index(0),
S: 3,
},
},
{
Output: ir.Index(4),
Op: ir.Add{
X: ir.Index(1),
Y: ir.Index(3),
},
},
},
}
err := CheckDanglingInputs(p)
if err == nil {
t.Fatal("expected error")
}
}
addchain-0.4.0/acc/printer/ 0000775 0000000 0000000 00000000000 15143052566 0015466 5 ustar 00root root 0000000 0000000 addchain-0.4.0/acc/printer/printer.go 0000664 0000000 0000000 00000004601 15143052566 0017501 0 ustar 00root root 0000000 0000000 // Package printer implements printing of acc AST nodes.
package printer
import (
"bytes"
"io"
"os"
"github.com/mmcloughlin/addchain/acc/ast"
"github.com/mmcloughlin/addchain/internal/errutil"
"github.com/mmcloughlin/addchain/internal/print"
)
// String prints the AST and returns resulting string.
func String(n interface{}) (string, error) {
b, err := Bytes(n)
if err != nil {
return "", err
}
return string(b), nil
}
// Bytes prints the AST and returns resulting bytes.
func Bytes(n interface{}) ([]byte, error) {
var buf bytes.Buffer
if err := Fprint(&buf, n); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
// Print an AST node to standard out.
func Print(n interface{}) error {
return Fprint(os.Stdout, n)
}
// Fprint writes the AST node n to w.
func Fprint(w io.Writer, n interface{}) error {
p := newprinter(w)
p.node(n)
p.Flush()
return p.Error()
}
type printer struct {
*print.TabWriter
}
func newprinter(w io.Writer) *printer {
return &printer{
TabWriter: print.NewTabWriter(w, 1, 4, 1, ' ', 0),
}
}
func (p *printer) node(n interface{}) {
switch n := n.(type) {
case *ast.Chain:
for _, stmt := range n.Statements {
p.statement(stmt)
}
case ast.Statement:
p.statement(n)
case ast.Expr:
p.expr(n, nil)
default:
p.SetError(errutil.UnexpectedType(n))
}
}
func (p *printer) statement(stmt ast.Statement) {
if len(stmt.Name) > 0 {
p.Printf("%s\t=\t", stmt.Name)
} else {
p.Printf("return\t\t")
}
p.expr(stmt.Expr, nil)
p.NL()
}
func (p *printer) expr(e, parent ast.Expr) {
// Parens required if the precence of this operator is less than its parent.
if parent != nil && e.Precedence() < parent.Precedence() {
p.Printf("(")
p.expr(e, nil)
p.Printf(")")
return
}
switch e := e.(type) {
case ast.Operand:
p.operand(e)
case ast.Identifier:
p.identifier(e)
case ast.Add:
p.add(e)
case ast.Double:
p.double(e)
case ast.Shift:
p.shift(e)
default:
p.SetError(errutil.UnexpectedType(e))
}
}
func (p *printer) add(a ast.Add) {
p.expr(a.X, a)
p.Printf(" + ")
p.expr(a.Y, a)
}
func (p *printer) double(d ast.Double) {
p.Printf("2*")
p.expr(d.X, d)
}
func (p *printer) shift(s ast.Shift) {
p.expr(s.X, s)
p.Printf(" << %d", s.S)
}
func (p *printer) identifier(name ast.Identifier) {
p.Printf("%s", name)
}
func (p *printer) operand(op ast.Operand) {
if op == 0 {
p.Printf("1")
} else {
p.Printf("[%d]", op)
}
}
addchain-0.4.0/acc/roundtrip_test.go 0000664 0000000 0000000 00000003351 15143052566 0017421 0 ustar 00root root 0000000 0000000 package acc
import (
"bytes"
"reflect"
"testing"
"github.com/mmcloughlin/addchain"
"github.com/mmcloughlin/addchain/acc/parse"
"github.com/mmcloughlin/addchain/acc/pass"
"github.com/mmcloughlin/addchain/acc/printer"
)
// The purpose of this test is to verify the full round trip from an addition
// chain program to source and back.
//
// addchain.Chain c
// | ^
// Program | | Evaluate
// v |
// addchain.Program p
// | ^
// Decompile | | Compile
// v |
// ir.Program r
// | ^
// Build | | Translate
// v |
// ast.Chain s
// | ^
// Print | | Parse
// v |
// acc source src
func TestRandomRoundTrip(t *testing.T) {
CheckRandom(t, func(t *testing.T, p addchain.Program) {
// Decompile into IR.
r, err := Decompile(p)
if err != nil {
t.Fatal(err)
}
// Build syntax tree.
s, err := Build(r)
if err != nil {
t.Fatal(err)
}
// Print to source.
var src bytes.Buffer
err = printer.Fprint(&src, s)
if err != nil {
t.Fatal(err)
}
// Parse back to syntax.
s2, err := parse.Reader("string", &src)
if err != nil {
t.Fatal(err)
}
// Translate back to IR.
r2, err := Translate(s2)
if err != nil {
t.Fatal(err)
}
// Compile back to a program.
if err := pass.Compile(r2); err != nil {
t.Fatal(err)
}
p2 := r2.Program
if !reflect.DeepEqual(p, p2) {
t.Logf("p:\n%v", p)
t.Logf("r:\n%v", r)
t.Logf("src:\n%s", src.String())
t.Logf("r2:\n%v", r2)
t.Logf("p2:\n%v", p2)
t.Fatal("roundtrip failure")
}
})
}
addchain-0.4.0/acc/translate.go 0000664 0000000 0000000 00000005046 15143052566 0016334 0 ustar 00root root 0000000 0000000 package acc
import (
"fmt"
"github.com/mmcloughlin/addchain/acc/ast"
"github.com/mmcloughlin/addchain/acc/ir"
"github.com/mmcloughlin/addchain/internal/errutil"
)
// Translate converts an abstract syntax tree to an intermediate representation.
func Translate(c *ast.Chain) (*ir.Program, error) {
s := newstate()
for _, stmt := range c.Statements {
if err := s.statement(stmt); err != nil {
return nil, err
}
}
return s.prog, nil
}
type state struct {
prog *ir.Program
n int
variable map[ast.Identifier]*ir.Operand
}
func newstate() *state {
return &state{
prog: &ir.Program{},
n: 1,
variable: map[ast.Identifier]*ir.Operand{},
}
}
func (s *state) statement(stmt ast.Statement) error {
out, err := s.expr(stmt.Expr)
if err != nil {
return err
}
if err := s.define(stmt.Name, out); err != nil {
return err
}
return nil
}
func (s *state) expr(expr ast.Expr) (*ir.Operand, error) {
switch e := expr.(type) {
case ast.Operand:
return &ir.Operand{Index: int(e)}, nil
case ast.Identifier:
return s.lookup(e)
case ast.Add:
return s.add(e)
case ast.Double:
return s.double(e)
case ast.Shift:
return s.shift(e)
default:
return nil, errutil.UnexpectedType(e)
}
}
func (s *state) add(a ast.Add) (*ir.Operand, error) {
x, err := s.expr(a.X)
if err != nil {
return nil, err
}
y, err := s.expr(a.Y)
if err != nil {
return nil, err
}
if x.Index > y.Index {
x, y = y, x
}
out := ir.Index(s.n)
inst := &ir.Instruction{
Output: out,
Op: ir.Add{X: x, Y: y},
}
s.prog.AddInstruction(inst)
s.n++
return out, nil
}
func (s *state) double(d ast.Double) (*ir.Operand, error) {
x, err := s.expr(d.X)
if err != nil {
return nil, err
}
out := ir.Index(s.n)
inst := &ir.Instruction{
Output: out,
Op: ir.Double{X: x},
}
s.prog.AddInstruction(inst)
s.n++
return out, nil
}
func (s *state) shift(sh ast.Shift) (*ir.Operand, error) {
x, err := s.expr(sh.X)
if err != nil {
return nil, err
}
s.n += int(sh.S)
out := ir.Index(s.n - 1)
inst := &ir.Instruction{
Output: out,
Op: ir.Shift{X: x, S: sh.S},
}
s.prog.AddInstruction(inst)
return out, nil
}
func (s *state) define(name ast.Identifier, op *ir.Operand) error {
if _, found := s.variable[name]; found {
return fmt.Errorf("cannot redefine %q", name)
}
op.Identifier = string(name)
s.variable[name] = op
return nil
}
func (s state) lookup(name ast.Identifier) (*ir.Operand, error) {
operand, ok := s.variable[name]
if !ok {
return nil, fmt.Errorf("variable %q undefined", name)
}
return operand, nil
}
addchain-0.4.0/acc/translate_test.go 0000664 0000000 0000000 00000002074 15143052566 0017371 0 ustar 00root root 0000000 0000000 package acc
import (
"reflect"
"testing"
"github.com/mmcloughlin/addchain/acc/ir"
"github.com/mmcloughlin/addchain/acc/parse"
)
func TestTranslateBasicOps(t *testing.T) {
src := "a = 1+1\nd = 2 * 1\n1 << 42"
expect := &ir.Program{
Instructions: []*ir.Instruction{
{
Output: &ir.Operand{
Index: 1,
Identifier: "a",
},
Op: ir.Add{
X: &ir.Operand{Index: 0},
Y: &ir.Operand{Index: 0},
},
},
{
Output: &ir.Operand{
Index: 2,
Identifier: "d",
},
Op: ir.Double{
X: &ir.Operand{Index: 0},
},
},
{
Output: &ir.Operand{
Index: 44,
},
Op: ir.Shift{
X: &ir.Operand{Index: 0},
S: 42,
},
},
},
}
AssertTranslate(t, src, expect)
}
func AssertTranslate(t *testing.T, src string, expect *ir.Program) {
t.Helper()
s, err := parse.String(src)
if err != nil {
t.Fatal(err)
}
p, err := Translate(s)
if err != nil {
t.Fatal(err)
}
t.Logf("got:\n%s", p)
if !reflect.DeepEqual(p, expect) {
t.Logf("expect:\n%s", expect)
t.Fatal("mismatch")
}
}
addchain-0.4.0/acc/util_test.go 0000664 0000000 0000000 00000001622 15143052566 0016347 0 ustar 00root root 0000000 0000000 package acc
import (
"testing"
"github.com/mmcloughlin/addchain"
"github.com/mmcloughlin/addchain/alg/contfrac"
"github.com/mmcloughlin/addchain/alg/dict"
"github.com/mmcloughlin/addchain/internal/test"
"github.com/mmcloughlin/addchain/rand"
)
// CheckRandom runs the check function against randomly generated chain programs.
func CheckRandom(t *testing.T, check func(t *testing.T, p addchain.Program)) {
gs := []rand.Generator{
rand.AddsGenerator{N: 10},
rand.NewSolverGenerator(
160,
dict.NewAlgorithm(
dict.SlidingWindow{K: 5},
contfrac.NewAlgorithm(contfrac.DichotomicStrategy{}),
),
),
}
for _, g := range gs {
g := g // scopelint
t.Run(g.String(), test.Trials(func(t *testing.T) bool {
c, err := g.GenerateChain()
if err != nil {
t.Fatal(err)
}
p, err := c.Program()
if err != nil {
t.Fatal(err)
}
check(t, p)
return true
}))
}
}
addchain-0.4.0/alg/ 0000775 0000000 0000000 00000000000 15143052566 0014020 5 ustar 00root root 0000000 0000000 addchain-0.4.0/alg/alg.go 0000664 0000000 0000000 00000002451 15143052566 0015114 0 ustar 00root root 0000000 0000000 // Package alg provides base types for addition chain and addition sequence search algorithms.
package alg
import (
"math/big"
"github.com/mmcloughlin/addchain"
)
// ChainAlgorithm is a method of generating an addition chain for a target integer.
type ChainAlgorithm interface {
// FindChain generates an addition chain ending at target.
FindChain(target *big.Int) (addchain.Chain, error)
// String returns a name for the algorithm.
String() string
}
// SequenceAlgorithm is a method of generating an addition sequence for a set of
// target values.
type SequenceAlgorithm interface {
// FindSequence generates an addition chain containing every element of targets.
FindSequence(targets []*big.Int) (addchain.Chain, error)
// String returns a name for the algorithm.
String() string
}
// AsChainAlgorithm adapts a sequence algorithm to a chain algorithm. The
// resulting algorithm calls the sequence algorithm with a singleton list
// containing the target.
func AsChainAlgorithm(s SequenceAlgorithm) ChainAlgorithm {
return asChainAlgorithm{s}
}
type asChainAlgorithm struct {
SequenceAlgorithm
}
// FindChain calls FindSequence with a singleton list containing the target.
func (a asChainAlgorithm) FindChain(target *big.Int) (addchain.Chain, error) {
return a.FindSequence([]*big.Int{target})
}
addchain-0.4.0/alg/algtest/ 0000775 0000000 0000000 00000000000 15143052566 0015463 5 ustar 00root root 0000000 0000000 addchain-0.4.0/alg/algtest/assert.go 0000664 0000000 0000000 00000002306 15143052566 0017314 0 ustar 00root root 0000000 0000000 package algtest
import (
"math/big"
"reflect"
"testing"
"github.com/mmcloughlin/addchain"
"github.com/mmcloughlin/addchain/alg"
)
// AssertChainAlgorithmGenerates asserts that the algorithm generates the expected chain for n.
func AssertChainAlgorithmGenerates(t *testing.T, a alg.ChainAlgorithm, n *big.Int, expect addchain.Chain) {
c, err := a.FindChain(n)
if err != nil {
t.Fatal(err)
}
if err := c.Validate(); err != nil {
t.Error(err)
}
if !reflect.DeepEqual(expect, c) {
t.Fatalf("got %v; expect %v", c, expect)
}
}
// AssertChainAlgorithmProduces verifies that a returns a valid chain for n.
func AssertChainAlgorithmProduces(t *testing.T, a alg.ChainAlgorithm, n *big.Int) addchain.Chain {
c, err := a.FindChain(n)
if err != nil {
t.Fatal(err)
}
err = c.Produces(n)
if err != nil {
t.Log(c)
t.Fatal(err)
}
return c
}
// AssertSequenceAlgorithmProduces verifies that a returns a valid chain containing targets.
func AssertSequenceAlgorithmProduces(t *testing.T, a alg.SequenceAlgorithm, targets []*big.Int) addchain.Chain {
c, err := a.FindSequence(targets)
if err != nil {
t.Fatal(err)
}
err = c.Superset(targets)
if err != nil {
t.Log(c)
t.Fatal(err)
}
return c
}
addchain-0.4.0/alg/algtest/chain.go 0000664 0000000 0000000 00000003522 15143052566 0017076 0 ustar 00root root 0000000 0000000 package algtest
import (
"math"
"math/big"
"math/rand"
"testing"
"github.com/mmcloughlin/addchain/alg"
"github.com/mmcloughlin/addchain/internal/bigint"
"github.com/mmcloughlin/addchain/internal/prime"
"github.com/mmcloughlin/addchain/internal/test"
)
// ChainAlgorithm applies a generic test suite to the algorithm a.
func ChainAlgorithm(t *testing.T, a alg.ChainAlgorithm) {
suite := ChainAlgorithmSuite(a)
suite(t)
}
// ChainAlgorithmSuite builds a generic test suite function for the algorithm a.
func ChainAlgorithmSuite(a alg.ChainAlgorithm) func(t *testing.T) {
return func(t *testing.T) {
t.Run("powers_of_two", checkPowersOfTwo(a, 100))
t.Run("binary_runs", checkBinaryRuns(a, 32))
t.Run("random_int64", checkRandomInt64s(a))
t.Run("primes", checkPrimes(a))
}
}
func checkPowersOfTwo(a alg.ChainAlgorithm, e uint) func(t *testing.T) {
return func(t *testing.T) {
n := big.NewInt(1)
for i := uint(0); i <= e; i++ {
AssertChainAlgorithmProduces(t, a, n)
n.Lsh(n, 1)
}
}
}
func checkBinaryRuns(a alg.ChainAlgorithm, n uint) func(t *testing.T) {
return func(t *testing.T) {
for i := uint(1); i <= n; i++ {
r := bigint.Pow2(i)
r.Sub(r, bigint.One())
AssertChainAlgorithmProduces(t, a, r)
}
}
}
func checkRandomInt64s(a alg.ChainAlgorithm) func(t *testing.T) {
return test.Trials(func(t *testing.T) bool {
r := rand.Int63n(math.MaxInt64)
n := big.NewInt(r)
AssertChainAlgorithmProduces(t, a, n)
return true
})
}
func checkPrimes(a alg.ChainAlgorithm) func(t *testing.T) {
// Prepare primes in a random order.
ps := []*big.Int{}
for _, p := range prime.Distinguished {
ps = append(ps, p.Int())
}
rand.Shuffle(len(ps), func(i, j int) { ps[i], ps[j] = ps[j], ps[i] })
return test.Trials(func(t *testing.T) bool {
AssertChainAlgorithmProduces(t, a, ps[0])
ps = ps[1:]
return len(ps) > 0
})
}
addchain-0.4.0/alg/algtest/doc.go 0000664 0000000 0000000 00000000103 15143052566 0016551 0 ustar 00root root 0000000 0000000 // Package algtest provides algorithm test suites.
package algtest
addchain-0.4.0/alg/algtest/seq.go 0000664 0000000 0000000 00000010102 15143052566 0016574 0 ustar 00root root 0000000 0000000 package algtest
import (
"math/big"
"testing"
"github.com/mmcloughlin/addchain"
"github.com/mmcloughlin/addchain/alg"
"github.com/mmcloughlin/addchain/internal/bigints"
)
// References:
//
// [curvechains] Brian Smith. The Most Efficient Known Addition Chains for Field Element and
// Scalar Inversion for the Most Popular and Most Unpopular Elliptic Curves. 2017.
// https://briansmith.org/ecc-inversion-addition-chains-01 (accessed June 30, 2019)
// [hehcc:exp] Christophe Doche. Exponentiation. Handbook of Elliptic and Hyperelliptic Curve
// Cryptography, chapter 9. 2006.
// http://koclab.cs.ucsb.edu/teaching/ecc/eccPapers/Doche-ch09.pdf
// [pairingsfinalexp] Michael Scott, Naomi Benger, Manuel Charlemagne, Luis J. Dominguez Perez and
// Ezekiel J. Kachisa. On the final exponentiation for calculating pairings on
// ordinary elliptic curves. Cryptology ePrint Archive, Report 2008/490. 2008.
// https://eprint.iacr.org/2008/490
// SequenceAlgorithmSuite builds a generic suite of tests for an addition
// sequence algorithm.
type SequenceAlgorithmSuite struct {
// Algorithm under test.
Algorithm alg.SequenceAlgorithm
// AcceptsLargeInputs indicates whether the algorithm can tolerate large
// inputs. As a rule of thumb, set this to true if the algorithm is
// logarithmic in the largest input.
AcceptsLargeInputs bool
}
// Tests builds the test suite function. Suitable to run as a subtest with
// testing.T.Run.
func (s SequenceAlgorithmSuite) Tests() func(t *testing.T) {
return func(t *testing.T) {
t.Run("known_sequences", checkKnownSequences(s.Algorithm))
if s.AcceptsLargeInputs {
t.Run("as_chain_algorithm", ChainAlgorithmSuite(alg.AsChainAlgorithm(s.Algorithm)))
}
}
}
func checkKnownSequences(a alg.SequenceAlgorithm) func(t *testing.T) {
cases := []struct {
Targets []*big.Int
Solution addchain.Chain
}{
// Example 9.39 in [hehcc:exp].
{
Targets: bigints.Int64s(47, 117, 343, 499, 933, 5689),
Solution: addchain.Int64s(1, 2, 4, 8, 10, 11, 18, 36, 47, 55, 91, 109, 117, 226, 343, 434, 489, 499, 933, 1422, 2844, 5688, 5689),
},
// [pairingsfinalexp] page 5.
{
Targets: bigints.Int64s(6, 12, 18, 30, 36),
Solution: addchain.Int64s(1, 2, 3, 6, 12, 18, 30, 36),
},
// [pairingsfinalexp] page 8.
{
Targets: bigints.Int64s(4, 5, 7, 10, 15, 26, 28, 30, 55, 75, 80, 100, 108, 144),
Solution: addchain.Int64s(1, 2, 4, 5, 7, 10, 15, 25, 26, 28, 30, 36, 50, 55, 75, 80, 100, 108, 144),
},
// [pairingsfinalexp] page 9.
{
Targets: bigints.Int64s(3, 5, 7, 14, 15, 21, 25, 35, 49, 54, 62, 70, 87, 98, 112, 245, 273, 319, 343, 434, 450, 581, 609, 784, 931, 1407, 1911, 4802, 6517),
Solution: addchain.Int64s(1, 2, 3, 4, 5, 7, 8, 14, 15, 16, 21, 25, 28, 35, 42, 49, 54, 62, 70, 87, 98, 112, 147, 245, 273, 294, 319, 343, 392, 434, 450, 581, 609, 784, 931, 1162, 1407, 1862, 1911, 3724, 4655, 4802, 6517),
},
// Curve25519 field inversion in [curvechains].
{
Targets: bigints.Int64s(1, 2, 250),
Solution: bigints.Int64s(1, 2, 3, 5, 10, 20, 40, 50, 100, 200, 250),
},
// P-256 field inversion in [curvechains].
{
Targets: bigints.Int64s(32, 94),
Solution: bigints.Int64s(1, 2, 3, 6, 12, 15, 30, 32, 64, 94),
},
// P-384 field inversion in [curvechains].
{
Targets: bigints.Int64s(30, 32, 255),
Solution: bigints.Int64s(1, 2, 3, 6, 12, 15, 30, 32, 60, 120, 240, 255),
},
// secp256k1 field inversion in [curvechains].
{
Targets: bigints.Int64s(22, 223),
Solution: bigints.Int64s(1, 2, 3, 6, 9, 11, 22, 44, 88, 176, 220, 223),
},
}
for _, c := range cases {
if err := c.Solution.Superset(c.Targets); err != nil {
panic(err)
}
}
return func(t *testing.T) {
for _, c := range cases {
got := AssertSequenceAlgorithmProduces(t, a, c.Targets)
t.Logf(" got: length=%d sequence=%v", len(got), got)
t.Logf("solution: length=%d sequence=%v", len(c.Solution), c.Solution)
if len(got) > len(c.Solution) {
t.Logf("sub-optimal")
}
}
}
}
addchain-0.4.0/alg/binary/ 0000775 0000000 0000000 00000000000 15143052566 0015304 5 ustar 00root root 0000000 0000000 addchain-0.4.0/alg/binary/binary.go 0000664 0000000 0000000 00000002063 15143052566 0017120 0 ustar 00root root 0000000 0000000 // Package binary implements generic binary addition chain algorithms.
package binary
import (
"math/big"
"github.com/mmcloughlin/addchain"
"github.com/mmcloughlin/addchain/internal/bigint"
)
// References:
//
// [hehcc:exp] Christophe Doche. Exponentiation. Handbook of Elliptic and Hyperelliptic Curve
// Cryptography, chapter 9. 2006.
// http://koclab.cs.ucsb.edu/teaching/ecc/eccPapers/Doche-ch09.pdf
// RightToLeft builds a chain algorithm for the right-to-left binary method,
// akin to [hehcc:exp] Algorithm 9.2.
type RightToLeft struct{}
func (RightToLeft) String() string { return "binary_right_to_left" }
// FindChain applies the right-to-left binary method to n.
func (RightToLeft) FindChain(n *big.Int) (addchain.Chain, error) {
c := addchain.Chain{}
b := new(big.Int).Set(n)
d := bigint.One()
var x *big.Int
for bigint.IsNonZero(b) {
c.AppendClone(d)
if b.Bit(0) == 1 {
if x == nil {
x = bigint.Clone(d)
} else {
x.Add(x, d)
c.AppendClone(x)
}
}
b.Rsh(b, 1)
d.Lsh(d, 1)
}
return c, nil
}
addchain-0.4.0/alg/binary/binary_test.go 0000664 0000000 0000000 00000000250 15143052566 0020153 0 ustar 00root root 0000000 0000000 package binary
import (
"testing"
"github.com/mmcloughlin/addchain/alg/algtest"
)
func TestRightToLeft(t *testing.T) {
algtest.ChainAlgorithm(t, RightToLeft{})
}
addchain-0.4.0/alg/contfrac/ 0000775 0000000 0000000 00000000000 15143052566 0015617 5 ustar 00root root 0000000 0000000 addchain-0.4.0/alg/contfrac/contfrac.go 0000664 0000000 0000000 00000020657 15143052566 0017757 0 ustar 00root root 0000000 0000000 // Package contfrac implements addition sequence algorithms based on continued-fraction expansions.
package contfrac
import (
"fmt"
"math/big"
"github.com/mmcloughlin/addchain"
"github.com/mmcloughlin/addchain/internal/bigint"
"github.com/mmcloughlin/addchain/internal/bigints"
)
// References:
//
// [contfrac] F Bergeron, J Berstel, S Brlek and C Duboc. Addition chains using continued
// fractions. Journal of Algorithms. 1989.
// http://www-igm.univ-mlv.fr/~berstel/Articles/1989AdditionChainDuboc.pdf
// [efficientcompaddchain] Bergeron, F., Berstel, J. and Brlek, S. Efficient computation of addition
// chains. Journal de theorie des nombres de Bordeaux. 1994.
// http://www.numdam.org/item/JTNB_1994__6_1_21_0
// [gencontfrac] Amadou Tall and Ali Yassin Sanghare. Efficient computation of
// addition-subtraction chains using generalized continued Fractions. Cryptology
// ePrint Archive, Report 2013/466. 2013. https://eprint.iacr.org/2013/466
// [hehcc:exp] Christophe Doche. Exponentiation. Handbook of Elliptic and Hyperelliptic Curve
// Cryptography, chapter 9. 2006.
// http://koclab.cs.ucsb.edu/teaching/ecc/eccPapers/Doche-ch09.pdf
// Strategy is a method of choosing the auxiliary integer k in the continued
// fraction method outlined in [efficientcompaddchain].
type Strategy interface {
// K returns values of k to try given n.
K(n *big.Int) []*big.Int
// Singleton returns whether every call to K will return one value of k. This
// determines whether the resulting continued fractions sequence algorithm will
// be logarithmic, and therefore suitable for large inputs.
Singleton() bool
// String returns a name for the strategy.
String() string
}
// Strategies lists all available continued fraction strategies.
var Strategies = []Strategy{
BinaryStrategy{},
CoBinaryStrategy{},
DichotomicStrategy{},
SqrtStrategy{},
TotalStrategy{},
DyadicStrategy{},
FermatStrategy{},
}
// Algorithm uses the continued fractions method for finding an addition chain
// [contfrac] [efficientcompaddchain].
type Algorithm struct {
strategy Strategy
}
// NewAlgorithm builds a continued fractions addition sequence algorithm using
// the provided strategy for selecting the auziallary integer k.
func NewAlgorithm(s Strategy) Algorithm {
return Algorithm{
strategy: s,
}
}
func (a Algorithm) String() string {
return fmt.Sprintf("continued_fractions(%s)", a.strategy)
}
// FindSequence applies the continued fractions method to build a chain
// containing targets.
func (a Algorithm) FindSequence(targets []*big.Int) (addchain.Chain, error) {
bigints.Sort(targets)
return a.chain(targets), nil
}
func (a Algorithm) minchain(n *big.Int) addchain.Chain {
if bigint.IsPow2(n) {
return bigint.Pow2UpTo(n)
}
if bigint.EqualInt64(n, 3) {
return bigints.Int64s(1, 2, 3)
}
var min addchain.Chain
for _, k := range a.strategy.K(n) {
c := a.chain([]*big.Int{k, n})
if min == nil || len(c) < len(min) {
min = c
}
}
return min
}
// chain produces a continued fraction chain for the given values. The slice ns
// must be in ascending order.
func (a Algorithm) chain(ns []*big.Int) addchain.Chain {
k := len(ns)
if k == 1 || ns[k-2].Cmp(bigint.One()) <= 0 {
return a.minchain(ns[k-1])
}
q, r := new(big.Int), new(big.Int)
q.DivMod(ns[k-1], ns[k-2], r)
cq := a.minchain(q)
remaining := bigints.Clone(ns[:k-1])
if bigint.IsZero(r) {
return addchain.Product(a.chain(remaining), cq)
}
remaining = bigints.InsertSortedUnique(remaining, r)
return addchain.Plus(addchain.Product(a.chain(remaining), cq), r)
}
// BinaryStrategy implements the binary strategy, which just sets k = floor(n/2). See [efficientcompaddchain] page 26.
// Since this is a singleton strategy it gives rise to a logarithmic sequence algoirithm that may not be optimal.
type BinaryStrategy struct{}
func (BinaryStrategy) String() string { return "binary" }
// Singleton returns true, since the binary strategy returns a single proposal
// for k.
func (BinaryStrategy) Singleton() bool { return true }
// K returns floor(n/2).
func (BinaryStrategy) K(n *big.Int) []*big.Int {
k := new(big.Int).Rsh(n, 1)
return []*big.Int{k}
}
// CoBinaryStrategy implements the co-binary strategy, also referred to as the
// "modified-binary" strategy. See [efficientcompaddchain] page 26 or
// [gencontfrac] page 6. Since this is a singleton strategy it gives rise to a
// logarithmic sequence algorithm that may not be optimal.
type CoBinaryStrategy struct{}
func (CoBinaryStrategy) String() string { return "co_binary" }
// Singleton returns true, since the co-binary strategy returns a single
// proposal for k.
func (CoBinaryStrategy) Singleton() bool { return true }
// K returns floor(n/2) when n is even, or floor((n+1)/2) when n is odd.
func (CoBinaryStrategy) K(n *big.Int) []*big.Int {
k := bigint.Clone(n)
if k.Bit(0) == 1 {
k.Add(k, bigint.One())
}
k.Rsh(k, 1)
return []*big.Int{k}
}
// TotalStrategy returns all possible values of k less than n. This will result
// in the optimal continued fraction chain at a complexity of O(n² log²(n)).
// Note that the optimal continued fraction chain is not necessarily the optimal
// chain. Must not be used for large inputs.
type TotalStrategy struct{}
func (TotalStrategy) String() string { return "total" }
// Singleton returns false, since the total strategy returns more than once k.
func (TotalStrategy) Singleton() bool { return false }
// K returns {2,, 3, ..., n-1}.
func (TotalStrategy) K(n *big.Int) []*big.Int {
ks := []*big.Int{}
k := big.NewInt(2)
one := bigint.One()
for k.Cmp(n) < 0 {
ks = append(ks, bigint.Clone(k))
k.Add(k, one)
}
return ks
}
// DyadicStrategy implements the Dyadic Strategy, defined in
// [efficientcompaddchain] page 28. This gives rise to a sequence algorithm with
// complexity O(n*log³(n)). Must not be used for large inputs.
type DyadicStrategy struct{}
func (DyadicStrategy) String() string { return "dyadic" }
// Singleton returns false, since the dyadic strategy returns more than once k.
func (DyadicStrategy) Singleton() bool { return false }
// K returns floor( n / 2ʲ ) for all j.
func (DyadicStrategy) K(n *big.Int) []*big.Int {
ks := []*big.Int{}
k := new(big.Int).Rsh(n, 1)
one := bigint.One()
for k.Cmp(one) > 0 {
ks = append(ks, bigint.Clone(k))
k.Rsh(k, 1)
}
return ks
}
// FermatStrategy implements Fermat's Strategy, defined in
// [efficientcompaddchain] page 28. This returns a set of possible k of size
// O(log(log(n))), giving rise to a faster algorithm than the Dyadic strategy.
// This has been shown to be near optimal for small inputs. Must not be used for
// large inputs.
type FermatStrategy struct{}
func (FermatStrategy) String() string { return "fermat" }
// Singleton returns false, since Fermat's strategy returns more than once k.
func (FermatStrategy) Singleton() bool { return false }
// K returns floor( n / 2^(2^j) ) for all j.
func (FermatStrategy) K(n *big.Int) []*big.Int {
ks := []*big.Int{}
k := new(big.Int).Rsh(n, 1)
one := bigint.One()
s := uint(1)
for k.Cmp(one) > 0 {
ks = append(ks, bigint.Clone(k))
k.Rsh(k, s)
s *= 2
}
return ks
}
// DichotomicStrategy is a singleton strategy, defined in
// [efficientcompaddchain] page 28. This gives rise to a logarithmic sequence
// algorithm, but the result is not necessarily optimal.
type DichotomicStrategy struct{}
func (DichotomicStrategy) String() string { return "dichotomic" }
// Singleton returns true, since the dichotomic strategy suggests just one k.
func (DichotomicStrategy) Singleton() bool { return true }
// K returns only one suggestion for k, namely floor( n / 2ʰ ) where h = log2(n)/2.
func (DichotomicStrategy) K(n *big.Int) []*big.Int {
l := n.BitLen()
h := uint(l) / 2
k := new(big.Int).Div(n, bigint.Pow2(h))
return []*big.Int{k}
}
// SqrtStrategy chooses k to be floor(sqrt(n)). See [gencontfrac] page 6. Since
// this is a singleton strategy, it gives rise to a logarithmic sequence
// algorithm that's not necessarily optimal.
type SqrtStrategy struct{}
func (SqrtStrategy) String() string { return "sqrt" }
// Singleton returns true, since the square root strategy suggests just one k.
func (SqrtStrategy) Singleton() bool { return false }
// K returns floor(sqrt(n)).
func (SqrtStrategy) K(n *big.Int) []*big.Int {
sqrt := new(big.Int).Sqrt(n)
return []*big.Int{sqrt}
}
addchain-0.4.0/alg/contfrac/contfrac_test.go 0000664 0000000 0000000 00000001672 15143052566 0021012 0 ustar 00root root 0000000 0000000 package contfrac
import (
"math/big"
"testing"
"github.com/mmcloughlin/addchain/alg"
"github.com/mmcloughlin/addchain/alg/algtest"
"github.com/mmcloughlin/addchain/internal/bigints"
)
func TestAlgorithms(t *testing.T) {
for _, strategy := range Strategies {
suite := algtest.SequenceAlgorithmSuite{
Algorithm: NewAlgorithm(strategy),
AcceptsLargeInputs: strategy.Singleton(),
}
t.Run(suite.Algorithm.String(), suite.Tests())
}
}
func TestBinaryStrategy(t *testing.T) {
a := alg.AsChainAlgorithm(NewAlgorithm(BinaryStrategy{}))
n := big.NewInt(87)
expect := bigints.Int64s(1, 2, 4, 5, 10, 20, 21, 42, 43, 86, 87)
algtest.AssertChainAlgorithmGenerates(t, a, n, expect)
}
func TestCoBinaryStrategy(t *testing.T) {
a := alg.AsChainAlgorithm(NewAlgorithm(CoBinaryStrategy{}))
n := big.NewInt(87)
expect := bigints.Int64s(1, 2, 3, 5, 10, 11, 21, 22, 43, 44, 87)
algtest.AssertChainAlgorithmGenerates(t, a, n, expect)
}
addchain-0.4.0/alg/dict/ 0000775 0000000 0000000 00000000000 15143052566 0014743 5 ustar 00root root 0000000 0000000 addchain-0.4.0/alg/dict/alg_test.go 0000664 0000000 0000000 00000001211 15143052566 0017067 0 ustar 00root root 0000000 0000000 package dict
import (
"testing"
"github.com/mmcloughlin/addchain/alg"
"github.com/mmcloughlin/addchain/alg/algtest"
"github.com/mmcloughlin/addchain/alg/contfrac"
)
func TestAlgorithms(t *testing.T) {
as := []alg.ChainAlgorithm{
// Dictionary-based algorithms.
NewAlgorithm(
SlidingWindow{K: 4},
contfrac.NewAlgorithm(contfrac.DichotomicStrategy{}),
),
NewAlgorithm(
FixedWindow{K: 7},
contfrac.NewAlgorithm(contfrac.BinaryStrategy{}),
),
// Runs algorithm.
NewRunsAlgorithm(contfrac.NewAlgorithm(contfrac.DichotomicStrategy{})),
}
for _, a := range as {
t.Run(a.String(), algtest.ChainAlgorithmSuite(a))
}
}
addchain-0.4.0/alg/dict/dict.go 0000664 0000000 0000000 00000025731 15143052566 0016225 0 ustar 00root root 0000000 0000000 // Package dict implements dictionary and run-length addition chain algorithms.
package dict
import (
"errors"
"fmt"
"math/big"
"sort"
"github.com/mmcloughlin/addchain"
"github.com/mmcloughlin/addchain/alg"
"github.com/mmcloughlin/addchain/internal/bigint"
"github.com/mmcloughlin/addchain/internal/bigints"
"github.com/mmcloughlin/addchain/internal/bigvector"
)
// References:
//
// [braueraddsubchains] Martin Otto. Brauer addition-subtraction chains. PhD thesis, Universitat
// Paderborn. 2001.
// http://www.martin-otto.de/publications/docs/2001_MartinOtto_Diplom_BrauerAddition-SubtractionChains.pdf
// [genshortchains] Kunihiro, Noboru and Yamamoto, Hirosuke. New Methods for Generating Short
// Addition Chains. IEICE Transactions on Fundamentals of Electronics
// Communications and Computer Sciences. 2000.
// https://pdfs.semanticscholar.org/b398/d10faca35af9ce5a6026458b251fd0a5640c.pdf
// [hehcc:exp] Christophe Doche. Exponentiation. Handbook of Elliptic and Hyperelliptic Curve
// Cryptography, chapter 9. 2006.
// http://koclab.cs.ucsb.edu/teaching/ecc/eccPapers/Doche-ch09.pdf
// Term represents the integer D * 2ᴱ.
type Term struct {
D *big.Int
E uint
}
// Int converts the term to an integer.
func (t Term) Int() *big.Int {
return new(big.Int).Lsh(t.D, t.E)
}
// Sum is the representation of an integer as a sum of dictionary terms. See
// [hehcc:exp] definition 9.34.
type Sum []Term
// Int computes the dictionary sum as an integer.
func (s Sum) Int() *big.Int {
x := bigint.Zero()
for _, t := range s {
x.Add(x, t.Int())
}
return x
}
// SortByExponent sorts terms in ascending order of the exponent E.
func (s Sum) SortByExponent() {
sort.Slice(s, func(i, j int) bool { return s[i].E < s[j].E })
}
// Dictionary returns the distinct D values in the terms of this sum. The values
// are returned in ascending order.
func (s Sum) Dictionary() []*big.Int {
dict := make([]*big.Int, 0, len(s))
for _, t := range s {
dict = append(dict, t.D)
}
bigints.Sort(dict)
return bigints.Unique(dict)
}
// Decomposer is a method of breaking an integer into a dictionary sum.
type Decomposer interface {
Decompose(x *big.Int) Sum
String() string
}
// FixedWindow breaks integers into k-bit windows.
type FixedWindow struct {
K uint // Window size.
}
func (w FixedWindow) String() string { return fmt.Sprintf("fixed_window(%d)", w.K) }
// Decompose represents x in terms of k-bit windows from left to right.
func (w FixedWindow) Decompose(x *big.Int) Sum {
sum := Sum{}
h := x.BitLen()
for h > 0 {
l := max(h-int(w.K), 0)
d := bigint.Extract(x, uint(l), uint(h))
if bigint.IsNonZero(d) {
sum = append(sum, Term{D: d, E: uint(l)})
}
h = l
}
sum.SortByExponent()
return sum
}
// SlidingWindow breaks integers into k-bit windows, skipping runs of zeros
// where possible. See [hehcc:exp] section 9.1.3 or [braueraddsubchains] section
// 1.2.3.
type SlidingWindow struct {
K uint // Window size.
}
func (w SlidingWindow) String() string { return fmt.Sprintf("sliding_window(%d)", w.K) }
// Decompose represents x in base 2ᵏ.
func (w SlidingWindow) Decompose(x *big.Int) Sum {
sum := Sum{}
h := x.BitLen() - 1
for h >= 0 {
// Find first 1.
for h >= 0 && x.Bit(h) == 0 {
h--
}
if h < 0 {
break
}
// Look down k positions.
l := max(h-int(w.K)+1, 0)
// Advance to the next 1.
for x.Bit(l) == 0 {
l++
}
sum = append(sum, Term{
D: bigint.Extract(x, uint(l), uint(h+1)),
E: uint(l),
})
h = l - 1
}
sum.SortByExponent()
return sum
}
// RunLength decomposes integers in to runs of 1s up to a maximal length. See
// [genshortchains] Section 3.1.
type RunLength struct {
T uint // Maximal run length. Zero means no limit.
}
func (r RunLength) String() string { return fmt.Sprintf("run_length(%d)", r.T) }
// Decompose breaks x into runs of 1 bits.
func (r RunLength) Decompose(x *big.Int) Sum {
sum := Sum{}
i := x.BitLen() - 1
for i >= 0 {
// Find first 1.
for i >= 0 && x.Bit(i) == 0 {
i--
}
if i < 0 {
break
}
// Look for the end of the run.
s := i
for i >= 0 && x.Bit(i) == 1 && (r.T == 0 || uint(s-i) < r.T) {
i--
}
// We have a run from s to i+1.
sum = append(sum, Term{
D: bigint.Ones(uint(s - i)),
E: uint(i + 1),
})
}
sum.SortByExponent()
return sum
}
// Hybrid is a mix of the sliding window and run length decomposition methods,
// similar to the "Hybrid Method" of [genshortchains] Section 3.3.
type Hybrid struct {
K uint // Window size.
T uint // Maximal run length. Zero means no limit.
}
func (h Hybrid) String() string { return fmt.Sprintf("hybrid(%d,%d)", h.K, h.T) }
// Decompose breaks x into k-bit sliding windows or runs of 1s up to length T.
func (h Hybrid) Decompose(x *big.Int) Sum {
sum := Sum{}
// Clone since we'll be modifying it.
y := bigint.Clone(x)
// Process runs of length at least K.
i := y.BitLen() - 1
for i >= 0 {
// Find first 1.
for i >= 0 && y.Bit(i) == 0 {
i--
}
if i < 0 {
break
}
// Look for the end of the run.
s := i
for i >= 0 && y.Bit(i) == 1 && (h.T == 0 || uint(s-i) < h.T) {
i--
}
// We have a run from s to i+1. Skip it if its short.
n := uint(s - i)
if n <= h.K {
continue
}
// Add it to the sum and remove it from the integer.
sum = append(sum, Term{
D: bigint.Ones(n),
E: uint(i + 1),
})
y.Xor(y, bigint.Mask(uint(i+1), uint(s+1)))
}
// Process what remains with a sliding window.
w := SlidingWindow{K: h.K}
rem := w.Decompose(y)
sum = append(sum, rem...)
sum.SortByExponent()
return sum
}
// Algorithm implements a general dictionary-based chain construction algorithm,
// as in [braueraddsubchains] Algorithm 1.26. This operates in three stages:
// decompose the target into a sum of dictionray terms, use a sequence algorithm
// to generate the dictionary, then construct the target from the dictionary
// terms.
type Algorithm struct {
decomp Decomposer
seqalg alg.SequenceAlgorithm
}
// NewAlgorithm builds a dictionary algorithm that breaks up integers using the
// decomposer d and uses the sequence algorithm s to generate dictionary
// entries.
func NewAlgorithm(d Decomposer, a alg.SequenceAlgorithm) *Algorithm {
return &Algorithm{
decomp: d,
seqalg: a,
}
}
func (a Algorithm) String() string {
return fmt.Sprintf("dictionary(%s,%s)", a.decomp, a.seqalg)
}
// FindChain builds an addition chain producing n. This works by using the
// configured Decomposer to represent n as a sum of dictionary terms, then
// delegating to the SequenceAlgorithm to build a chain producing the
// dictionary, and finally using the dictionary terms to construct n. See
// [genshortchains] Section 2 for a full description.
func (a Algorithm) FindChain(n *big.Int) (addchain.Chain, error) {
// Decompose the target.
sum := a.decomp.Decompose(n)
sum.SortByExponent()
// Extract dictionary.
dict := sum.Dictionary()
// Use the sequence algorithm to produce a chain for each element of the dictionary.
c, err := a.seqalg.FindSequence(dict)
if err != nil {
return nil, err
}
// Reduce.
sum, c, err = primitive(sum, c)
if err != nil {
return nil, err
}
// Build chain for n out of the dictionary.
dc := dictsumchain(sum)
c = append(c, dc...)
bigints.Sort(c)
c = addchain.Chain(bigints.Unique(c))
return c, nil
}
// dictsumchain builds a chain for the integer represented by sum, assuming that
// all the terms of the sum are already present. Therefore this is intended to
// be appended to a chain that already contains the dictionary terms.
func dictsumchain(sum Sum) addchain.Chain {
c := addchain.Chain{}
k := len(sum) - 1
cur := bigint.Clone(sum[k].D)
for ; k > 0; k-- {
// Shift until the next exponent.
for i := sum[k].E; i > sum[k-1].E; i-- {
cur.Lsh(cur, 1)
c.AppendClone(cur)
}
// Add in the dictionary term at this position.
cur.Add(cur, sum[k-1].D)
c.AppendClone(cur)
}
for i := sum[0].E; i > 0; i-- {
cur.Lsh(cur, 1)
c.AppendClone(cur)
}
return c
}
// primitive removes terms from the dictionary that are only required once.
//
// The general structure of dictionary based algorithm is to decompose the
// target into a sum of dictionary terms, then create a chain for the
// dictionary, and then create the target from that. In a case where a
// dictionary term is only required once in the target, this can cause extra
// work. In such a case, we will spend operations on creating the dictionary
// term independently, and then later add it into the result. Since it is only
// needed once, we can effectively construct the dictionary term "on the fly" as
// we build up the final target.
//
// This function looks for such opportunities. If it finds them it will produce
// an alternative dictionary sum that replaces that term with a sum of smaller
// terms.
func primitive(sum Sum, c addchain.Chain) (Sum, addchain.Chain, error) {
// This optimization cannot apply if the sum has only one term.
if len(sum) == 1 {
return sum, c, nil
}
n := len(c)
// We'll need a mapping from chain elements to where they appear in the chain.
idx := map[string]int{}
for i, x := range c {
idx[x.String()] = i
}
// Build program for the chain.
p, err := c.Program()
if err != nil {
return nil, nil, err
}
// How many times is each index read during construction, and during its use in the dictionary chain.
reads := p.ReadCounts()
for _, t := range sum {
i := idx[t.D.String()]
reads[i]++
}
// Now, the primitive dictionary elements are those that are read at least twice, and their dependencies.
deps := p.Dependencies()
primitive := make([]bool, n)
for i, numreads := range reads {
if numreads < 2 {
continue
}
primitive[i] = true
for _, j := range bigint.BitsSet(deps[i]) {
primitive[j] = true
}
}
// Express every position in the chain as a linear combination of dictionary
// terms that are used more than once.
vc := []bigvector.Vector{bigvector.NewBasis(n, 0)}
for i, op := range p {
var next bigvector.Vector
if primitive[i+1] {
next = bigvector.NewBasis(n, i+1)
} else {
next = bigvector.Add(vc[op.I], vc[op.J])
}
vc = append(vc, next)
}
// Now express the target sum in terms that are used more than once.
v := bigvector.New(n)
for _, t := range sum {
i := idx[t.D.String()]
v = bigvector.Add(v, bigvector.Lsh(vc[i], t.E))
}
// Rebuild this into a dictionary sum.
out := Sum{}
for i := 0; i < v.Len(); i++ {
for _, e := range bigint.BitsSet(v.Idx(i)) {
out = append(out, Term{
D: c[i],
E: uint(e),
})
}
}
out.SortByExponent()
// We should have not changed the sum.
if !bigint.Equal(out.Int(), sum.Int()) {
return nil, nil, errors.New("reconstruction does not match")
}
// Prune any elements of the chain that are used only once.
pruned := addchain.Chain{}
for i, x := range c {
if primitive[i] {
pruned = append(pruned, x)
}
}
return out, pruned, nil
}
// max returns the maximum of a and b.
func max(a, b int) int {
if a > b {
return a
}
return b
}
addchain-0.4.0/alg/dict/dict_test.go 0000664 0000000 0000000 00000011435 15143052566 0017260 0 ustar 00root root 0000000 0000000 package dict
import (
"math/big"
"math/rand"
"testing"
"time"
"github.com/mmcloughlin/addchain"
"github.com/mmcloughlin/addchain/alg/algtest"
"github.com/mmcloughlin/addchain/alg/contfrac"
"github.com/mmcloughlin/addchain/internal/bigint"
"github.com/mmcloughlin/addchain/internal/bigints"
"github.com/mmcloughlin/addchain/internal/test"
)
func TestDecomposersRandom(t *testing.T) {
ds := []Decomposer{
FixedWindow{K: 2},
FixedWindow{K: 11},
FixedWindow{K: 16},
SlidingWindow{K: 2},
SlidingWindow{K: 7},
SlidingWindow{K: 12},
RunLength{T: 0},
RunLength{T: 1},
RunLength{T: 3},
RunLength{T: 7},
Hybrid{K: 4, T: 7},
Hybrid{K: 3, T: 0},
}
r := rand.New(rand.NewSource(time.Now().UnixNano()))
for _, d := range ds {
d := d
t.Run(d.String(), test.Trials(func(t *testing.T) bool {
n := bigint.RandBits(r, 256)
got := d.Decompose(n)
if !bigint.Equal(got.Int(), n) {
t.Log(got)
t.Fatalf("got %v expect %v", got.Int(), n)
}
return true
}))
}
}
func TestFixedWindow(t *testing.T) {
n := big.NewInt(0xbeef0 << 3)
f := FixedWindow{K: 4}
got := f.Decompose(n)
expect := Sum{
{D: big.NewInt(0xf), E: 7},
{D: big.NewInt(0xe), E: 11},
{D: big.NewInt(0xe), E: 15},
{D: big.NewInt(0xb), E: 19},
}
if !SumEquals(got, expect) {
t.Fatalf("got %v expect %v", got, expect)
}
}
func TestSlidingWindow(t *testing.T) {
n := big.NewInt(0xf143)
f := SlidingWindow{K: 4}
got := f.Decompose(n)
expect := Sum{
{D: big.NewInt(0x3), E: 0},
{D: big.NewInt(0x5), E: 6},
{D: big.NewInt(0xf), E: 12},
}
if !SumEquals(got, expect) {
t.Fatalf("got %v expect %v", got, expect)
}
}
func TestRunLength(t *testing.T) {
cases := []struct {
T uint
X int64
Expect Sum
}{
{
T: 4,
X: 0xff,
Expect: Sum{
{D: big.NewInt(0xf), E: 0},
{D: big.NewInt(0xf), E: 4},
},
},
{
T: 0,
X: 0xff,
Expect: Sum{
{D: big.NewInt(0xff), E: 0},
},
},
{
T: 4,
X: 0xf0f0,
Expect: Sum{
{D: big.NewInt(0xf), E: 4},
{D: big.NewInt(0xf), E: 12},
},
},
{
T: 0,
X: 0xf0f0,
Expect: Sum{
{D: big.NewInt(0xf), E: 4},
{D: big.NewInt(0xf), E: 12},
},
},
{
T: 3,
X: 0xff,
Expect: Sum{
{D: big.NewInt(0x3), E: 0},
{D: big.NewInt(0x7), E: 2},
{D: big.NewInt(0x7), E: 5},
},
},
}
for _, c := range cases {
d := RunLength{T: c.T}
if got := d.Decompose(big.NewInt(c.X)); !SumEquals(got, c.Expect) {
t.Fatalf("Decompose(%#x) = %v; expect %v", c.X, got, c.Expect)
}
}
}
func TestHybrid(t *testing.T) {
n := bigint.MustBinary("11111111_11111111_000_111_000000_1_0_111111_0_11_0")
f := Hybrid{K: 4, T: 8}
got := f.Decompose(n)
expect := Sum{
{D: big.NewInt(0x3), E: 1},
{D: big.NewInt(0x3f), E: 4},
{D: big.NewInt(0x1), E: 11},
{D: big.NewInt(0x7), E: 18},
{D: big.NewInt(0xff), E: 24},
{D: big.NewInt(0xff), E: 32},
}
if !SumEquals(got, expect) {
t.Fatalf("got %v expect %v", got, expect)
}
}
func TestAlgorithm(t *testing.T) {
a := NewAlgorithm(
SlidingWindow{K: 4},
contfrac.NewAlgorithm(contfrac.DichotomicStrategy{}),
)
n := big.NewInt(587257)
c := algtest.AssertChainAlgorithmProduces(t, a, n)
t.Log(c)
}
func TestPrimitive(t *testing.T) {
// These tests are designed to verify that primitive dictionary reduction is
// doing sensible things, therefore we construct a dictionary algorithm with a
// decomposer that's going to have obvious results. We'll use the run length
// decomposer.
a := NewAlgorithm(
RunLength{T: 0},
contfrac.NewAlgorithm(contfrac.TotalStrategy{}),
)
// Cases are accompanied by an example of how this chain might be constructed
// if dictionary reduction is working. We simply confirm that the resulting
// chain is valid and at least as good as the example.
cases := []struct {
N *big.Int
Example addchain.Chain
}{
{
N: bigint.MustBinary("1111_0_1_0"),
Example: bigints.Int64s(
1, 2, 3, // prep
6, 12, 15, // << 2 and add 3
30, 60, 61, // << 2 and add 1
122, // << 1
),
},
{
N: bigint.MustBinary("11_0_11111111_0"),
Example: bigints.Int64s(
1, 2, 3, 6, 12, 15, // prepare 11 and 1111
24, 48, 96, 111, // << 5 add 1111
222, 444, 888, 1776, 1791, // << 4 add 1111
3582, // << 1
),
},
}
for _, c := range cases {
got := algtest.AssertChainAlgorithmProduces(t, a, c.N)
if err := c.Example.Produces(c.N); err != nil {
t.Fatalf("example is invalid: %s", err)
}
if len(got) > len(c.Example) {
t.Logf(" got: %v", got)
t.Logf("example: %v", c.Example)
t.Errorf("suboptimal result: length %d but possible in %d", len(got), len(c.Example))
}
}
}
func SumEquals(a, b Sum) bool {
if len(a) != len(b) {
return false
}
for i := range a {
if a[i].E != b[i].E {
return false
}
if !bigint.Equal(a[i].D, b[i].D) {
return false
}
}
return true
}
addchain-0.4.0/alg/dict/runs.go 0000664 0000000 0000000 00000005574 15143052566 0016274 0 ustar 00root root 0000000 0000000 package dict
import (
"errors"
"fmt"
"math/big"
"github.com/mmcloughlin/addchain"
"github.com/mmcloughlin/addchain/alg"
"github.com/mmcloughlin/addchain/internal/bigint"
"github.com/mmcloughlin/addchain/internal/bigints"
)
// RunsAlgorithm is a custom variant of the dictionary approach that decomposes
// a target into runs of ones. It leverages the observation that building a
// dictionary consisting of runs of 1s of lengths l₁, l₂, ..., l_k can itself
// be reduced to first finding an addition chain for the run lengths. Then from
// this chain we can build a chain for the runs themselves.
type RunsAlgorithm struct {
seqalg alg.SequenceAlgorithm
}
// NewRunsAlgorithm constructs a RunsAlgorithm using the given sequence
// algorithm to generate addition sequences for run lengths. Note that since run
// lengths are far smaller than the integers themselves, this sequence algorithm
// does not need to be able to handle large integers.
func NewRunsAlgorithm(a alg.SequenceAlgorithm) *RunsAlgorithm {
return &RunsAlgorithm{
seqalg: a,
}
}
func (a RunsAlgorithm) String() string {
return fmt.Sprintf("runs(%s)", a.seqalg)
}
// FindChain uses the run lengths method to find a chain for n.
func (a RunsAlgorithm) FindChain(n *big.Int) (addchain.Chain, error) {
// Find the runs in n.
d := RunLength{T: 0}
sum := d.Decompose(n)
runs := sum.Dictionary()
// Treat the run lengths themselves as a sequence to be solved.
lengths := []*big.Int{}
for _, run := range runs {
length := int64(run.BitLen())
lengths = append(lengths, big.NewInt(length))
}
// Delegate to the sequence algorithm for a solution.
lc, err := a.seqalg.FindSequence(lengths)
if err != nil {
return nil, err
}
// Build a dictionary chain from this.
c, err := RunsChain(lc)
if err != nil {
return nil, err
}
// Reduce.
sum, c, err = primitive(sum, c)
if err != nil {
return nil, err
}
// Build chain for n out of the dictionary.
dc := dictsumchain(sum)
c = append(c, dc...)
bigints.Sort(c)
c = addchain.Chain(bigints.Unique(c))
return c, nil
}
// RunsChain takes a chain for the run lengths and generates a chain for the
// runs themselves. That is, if the provided chain is l₁, l₂, ..., l_k then
// the result will contain r(l₁), r(l₂), ..., r(l_k) where r(n) = 2ⁿ - 1.
func RunsChain(lc addchain.Chain) (addchain.Chain, error) {
p, err := lc.Program()
if err != nil {
return nil, err
}
c := addchain.New()
s := map[uint]uint{} // current largest shift of each run length
for _, op := range p {
a, b := bigint.MinMax(lc[op.I], lc[op.J])
if !a.IsUint64() || !b.IsUint64() {
return nil, errors.New("values in lengths chain are far too large")
}
la := uint(a.Uint64())
lb := uint(b.Uint64())
rb := bigint.Ones(lb)
for ; s[lb] < la; s[lb]++ {
shift := new(big.Int).Lsh(rb, s[lb]+1)
c = append(c, shift)
}
c = append(c, bigint.Ones(la+lb))
}
return c, nil
}
addchain-0.4.0/alg/dict/runs_test.go 0000664 0000000 0000000 00000001567 15143052566 0017331 0 ustar 00root root 0000000 0000000 package dict
import (
"math/big"
"testing"
"github.com/mmcloughlin/addchain"
"github.com/mmcloughlin/addchain/internal/bigint"
)
func TestRunsChain(t *testing.T) {
cases := []addchain.Chain{
// Basic case.
addchain.Int64s(1, 2, 4, 6),
// The following induces a bug in an earlier incorrect implementation. Note
// that 9 and 12 are formed with 1+8 and 3+8, therfore both using 8 as the
// larger of the two operands. This means that shifts of Ones(8) are required
// on two occasions, causing a duplicate if you're not careful.
addchain.Int64s(1, 2, 4, 8, 9, 12),
}
for _, lengths := range cases {
runs := []*big.Int{}
for _, length := range lengths {
runs = append(runs, bigint.Ones(uint(length.Uint64())))
}
got, err := RunsChain(lengths)
if err != nil {
t.Fatal(err)
}
if err := got.Superset(runs); err != nil {
t.Fatal(err)
}
}
}
addchain-0.4.0/alg/ensemble/ 0000775 0000000 0000000 00000000000 15143052566 0015612 5 ustar 00root root 0000000 0000000 addchain-0.4.0/alg/ensemble/ensemble.go 0000664 0000000 0000000 00000003621 15143052566 0017735 0 ustar 00root root 0000000 0000000 // Package ensemble provides a collection of addition chain algorithms intended
// for target integers of cryptographic interest.
package ensemble
import (
"github.com/mmcloughlin/addchain/alg"
"github.com/mmcloughlin/addchain/alg/contfrac"
"github.com/mmcloughlin/addchain/alg/dict"
"github.com/mmcloughlin/addchain/alg/heuristic"
"github.com/mmcloughlin/addchain/alg/opt"
)
// Ensemble is a convenience for building an ensemble of chain algorithms intended for large integers.
func Ensemble() []alg.ChainAlgorithm {
// Choose sequence algorithms.
seqalgs := []alg.SequenceAlgorithm{
heuristic.NewAlgorithm(heuristic.UseFirst(
heuristic.Halving{},
heuristic.DeltaLargest{},
)),
heuristic.NewAlgorithm(heuristic.UseFirst(
heuristic.Halving{},
heuristic.Approximation{},
)),
}
for _, strategy := range contfrac.Strategies {
if strategy.Singleton() {
seqalgs = append(seqalgs, contfrac.NewAlgorithm(strategy))
}
}
// Build decomposers.
decomposers := []dict.Decomposer{}
for k := uint(4); k <= 128; k *= 2 {
decomposers = append(decomposers, dict.SlidingWindow{K: k})
}
decomposers = append(decomposers, dict.RunLength{T: 0})
for t := uint(16); t <= 128; t *= 2 {
decomposers = append(decomposers, dict.RunLength{T: t})
}
for k := uint(2); k <= 8; k++ {
decomposers = append(decomposers, dict.Hybrid{K: k, T: 0})
for t := uint(16); t <= 64; t *= 2 {
decomposers = append(decomposers, dict.Hybrid{K: k, T: t})
}
}
// Build dictionary algorithms for every combination.
as := []alg.ChainAlgorithm{}
for _, decomp := range decomposers {
for _, seqalg := range seqalgs {
a := dict.NewAlgorithm(decomp, seqalg)
as = append(as, a)
}
}
// Add the runs algorithms.
for _, seqalg := range seqalgs {
as = append(as, dict.NewRunsAlgorithm(seqalg))
}
// Wrap in an optimization layer.
for i, a := range as {
as[i] = opt.Algorithm{Algorithm: a}
}
return as
}
addchain-0.4.0/alg/ensemble/ensemble_test.go 0000664 0000000 0000000 00000004316 15143052566 0020776 0 ustar 00root root 0000000 0000000 package ensemble
import (
"encoding/json"
"io/ioutil"
"reflect"
"testing"
"github.com/mmcloughlin/addchain/alg/exec"
"github.com/mmcloughlin/addchain/internal/results"
"github.com/mmcloughlin/addchain/internal/test"
)
// TestResults confirms that chain lengths from every ensemble algorithm remain
// unchanged. This is intended to provide confidence when making risky changes
// or refactors. The results package has its own similar test, but this is
// focussed on verifying that the best recorded result is still the same.
//
// The test uses the "golden test" technique, where we dump
// known-good results into golden files and later verify that we get the same
// result.
func TestResults(t *testing.T) {
t.Parallel()
as := Ensemble()
for _, c := range results.Results {
c := c // scopelint
t.Run(c.Slug, func(t *testing.T) {
t.Parallel()
// Execute.
ex := exec.NewParallel()
rs := ex.Execute(c.Target(), as)
// Summarize results in map from algorithm name to program length.
got := map[string]int{}
for _, r := range rs {
if r.Err != nil {
t.Fatalf("error with %s: %v", r.Algorithm, r.Err)
}
got[r.Algorithm.String()] = len(r.Program)
}
// If golden, write out results data file.
filename := test.GoldenName(c.Slug)
if test.Golden() {
t.Logf("writing golden file %s", filename)
b, err := json.MarshalIndent(got, "", "\t")
if err != nil {
t.Fatal(err)
}
if err := ioutil.WriteFile(filename, b, 0644); err != nil {
t.Fatalf("write golden file: %v", err)
}
}
// Load golden file.
b, err := ioutil.ReadFile(filename)
if err != nil {
t.Fatalf("read golden file: %v", err)
}
var expect map[string]int
if err := json.Unmarshal(b, &expect); err != nil {
t.Fatal(err)
}
// Verify equal.
if !reflect.DeepEqual(expect, got) {
t.Fatal("results do not match golden file")
}
})
}
}
func BenchmarkResults(b *testing.B) {
as := Ensemble()
for _, c := range results.Results {
c := c // scopelint
n := c.Target()
b.Run(c.Slug, func(b *testing.B) {
for i := 0; i < b.N; i++ {
for _, a := range as {
if _, err := a.FindChain(n); err != nil {
b.Fatal(err)
}
}
}
})
}
}
addchain-0.4.0/alg/ensemble/testdata/ 0000775 0000000 0000000 00000000000 15143052566 0017423 5 ustar 00root root 0000000 0000000 addchain-0.4.0/alg/ensemble/testdata/curve25519_field.golden 0000664 0000000 0000000 00000035321 15143052566 0023516 0 ustar 00root root 0000000 0000000 {
"opt(dictionary(hybrid(2,0),continued_fractions(binary)))": 381,
"opt(dictionary(hybrid(2,0),continued_fractions(co_binary)))": 381,
"opt(dictionary(hybrid(2,0),continued_fractions(dichotomic)))": 268,
"opt(dictionary(hybrid(2,0),heuristic(use_first(halving,approximation))))": 381,
"opt(dictionary(hybrid(2,0),heuristic(use_first(halving,delta_largest))))": 502,
"opt(dictionary(hybrid(2,16),continued_fractions(binary)))": 276,
"opt(dictionary(hybrid(2,16),continued_fractions(co_binary)))": 276,
"opt(dictionary(hybrid(2,16),continued_fractions(dichotomic)))": 276,
"opt(dictionary(hybrid(2,16),heuristic(use_first(halving,approximation))))": 276,
"opt(dictionary(hybrid(2,16),heuristic(use_first(halving,delta_largest))))": 276,
"opt(dictionary(hybrid(2,32),continued_fractions(binary)))": 271,
"opt(dictionary(hybrid(2,32),continued_fractions(co_binary)))": 271,
"opt(dictionary(hybrid(2,32),continued_fractions(dichotomic)))": 270,
"opt(dictionary(hybrid(2,32),heuristic(use_first(halving,approximation))))": 271,
"opt(dictionary(hybrid(2,32),heuristic(use_first(halving,delta_largest))))": 281,
"opt(dictionary(hybrid(2,64),continued_fractions(binary)))": 272,
"opt(dictionary(hybrid(2,64),continued_fractions(co_binary)))": 272,
"opt(dictionary(hybrid(2,64),continued_fractions(dichotomic)))": 268,
"opt(dictionary(hybrid(2,64),heuristic(use_first(halving,approximation))))": 272,
"opt(dictionary(hybrid(2,64),heuristic(use_first(halving,delta_largest))))": 310,
"opt(dictionary(hybrid(3,0),continued_fractions(binary)))": 381,
"opt(dictionary(hybrid(3,0),continued_fractions(co_binary)))": 381,
"opt(dictionary(hybrid(3,0),continued_fractions(dichotomic)))": 268,
"opt(dictionary(hybrid(3,0),heuristic(use_first(halving,approximation))))": 341,
"opt(dictionary(hybrid(3,0),heuristic(use_first(halving,delta_largest))))": 503,
"opt(dictionary(hybrid(3,16),continued_fractions(binary)))": 276,
"opt(dictionary(hybrid(3,16),continued_fractions(co_binary)))": 276,
"opt(dictionary(hybrid(3,16),continued_fractions(dichotomic)))": 276,
"opt(dictionary(hybrid(3,16),heuristic(use_first(halving,approximation))))": 277,
"opt(dictionary(hybrid(3,16),heuristic(use_first(halving,delta_largest))))": 277,
"opt(dictionary(hybrid(3,32),continued_fractions(binary)))": 271,
"opt(dictionary(hybrid(3,32),continued_fractions(co_binary)))": 271,
"opt(dictionary(hybrid(3,32),continued_fractions(dichotomic)))": 270,
"opt(dictionary(hybrid(3,32),heuristic(use_first(halving,approximation))))": 271,
"opt(dictionary(hybrid(3,32),heuristic(use_first(halving,delta_largest))))": 284,
"opt(dictionary(hybrid(3,64),continued_fractions(binary)))": 272,
"opt(dictionary(hybrid(3,64),continued_fractions(co_binary)))": 272,
"opt(dictionary(hybrid(3,64),continued_fractions(dichotomic)))": 268,
"opt(dictionary(hybrid(3,64),heuristic(use_first(halving,approximation))))": 273,
"opt(dictionary(hybrid(3,64),heuristic(use_first(halving,delta_largest))))": 311,
"opt(dictionary(hybrid(4,0),continued_fractions(binary)))": 381,
"opt(dictionary(hybrid(4,0),continued_fractions(co_binary)))": 381,
"opt(dictionary(hybrid(4,0),continued_fractions(dichotomic)))": 277,
"opt(dictionary(hybrid(4,0),heuristic(use_first(halving,approximation))))": 320,
"opt(dictionary(hybrid(4,0),heuristic(use_first(halving,delta_largest))))": 502,
"opt(dictionary(hybrid(4,16),continued_fractions(binary)))": 276,
"opt(dictionary(hybrid(4,16),continued_fractions(co_binary)))": 276,
"opt(dictionary(hybrid(4,16),continued_fractions(dichotomic)))": 276,
"opt(dictionary(hybrid(4,16),heuristic(use_first(halving,approximation))))": 276,
"opt(dictionary(hybrid(4,16),heuristic(use_first(halving,delta_largest))))": 276,
"opt(dictionary(hybrid(4,32),continued_fractions(binary)))": 271,
"opt(dictionary(hybrid(4,32),continued_fractions(co_binary)))": 271,
"opt(dictionary(hybrid(4,32),continued_fractions(dichotomic)))": 270,
"opt(dictionary(hybrid(4,32),heuristic(use_first(halving,approximation))))": 271,
"opt(dictionary(hybrid(4,32),heuristic(use_first(halving,delta_largest))))": 282,
"opt(dictionary(hybrid(4,64),continued_fractions(binary)))": 272,
"opt(dictionary(hybrid(4,64),continued_fractions(co_binary)))": 272,
"opt(dictionary(hybrid(4,64),continued_fractions(dichotomic)))": 268,
"opt(dictionary(hybrid(4,64),heuristic(use_first(halving,approximation))))": 272,
"opt(dictionary(hybrid(4,64),heuristic(use_first(halving,delta_largest))))": 310,
"opt(dictionary(hybrid(5,0),continued_fractions(binary)))": 381,
"opt(dictionary(hybrid(5,0),continued_fractions(co_binary)))": 381,
"opt(dictionary(hybrid(5,0),continued_fractions(dichotomic)))": 277,
"opt(dictionary(hybrid(5,0),heuristic(use_first(halving,approximation))))": 320,
"opt(dictionary(hybrid(5,0),heuristic(use_first(halving,delta_largest))))": 502,
"opt(dictionary(hybrid(5,16),continued_fractions(binary)))": 276,
"opt(dictionary(hybrid(5,16),continued_fractions(co_binary)))": 276,
"opt(dictionary(hybrid(5,16),continued_fractions(dichotomic)))": 276,
"opt(dictionary(hybrid(5,16),heuristic(use_first(halving,approximation))))": 276,
"opt(dictionary(hybrid(5,16),heuristic(use_first(halving,delta_largest))))": 276,
"opt(dictionary(hybrid(5,32),continued_fractions(binary)))": 271,
"opt(dictionary(hybrid(5,32),continued_fractions(co_binary)))": 271,
"opt(dictionary(hybrid(5,32),continued_fractions(dichotomic)))": 270,
"opt(dictionary(hybrid(5,32),heuristic(use_first(halving,approximation))))": 271,
"opt(dictionary(hybrid(5,32),heuristic(use_first(halving,delta_largest))))": 282,
"opt(dictionary(hybrid(5,64),continued_fractions(binary)))": 272,
"opt(dictionary(hybrid(5,64),continued_fractions(co_binary)))": 272,
"opt(dictionary(hybrid(5,64),continued_fractions(dichotomic)))": 268,
"opt(dictionary(hybrid(5,64),heuristic(use_first(halving,approximation))))": 272,
"opt(dictionary(hybrid(5,64),heuristic(use_first(halving,delta_largest))))": 310,
"opt(dictionary(hybrid(6,0),continued_fractions(binary)))": 381,
"opt(dictionary(hybrid(6,0),continued_fractions(co_binary)))": 381,
"opt(dictionary(hybrid(6,0),continued_fractions(dichotomic)))": 277,
"opt(dictionary(hybrid(6,0),heuristic(use_first(halving,approximation))))": 320,
"opt(dictionary(hybrid(6,0),heuristic(use_first(halving,delta_largest))))": 502,
"opt(dictionary(hybrid(6,16),continued_fractions(binary)))": 276,
"opt(dictionary(hybrid(6,16),continued_fractions(co_binary)))": 276,
"opt(dictionary(hybrid(6,16),continued_fractions(dichotomic)))": 276,
"opt(dictionary(hybrid(6,16),heuristic(use_first(halving,approximation))))": 276,
"opt(dictionary(hybrid(6,16),heuristic(use_first(halving,delta_largest))))": 276,
"opt(dictionary(hybrid(6,32),continued_fractions(binary)))": 271,
"opt(dictionary(hybrid(6,32),continued_fractions(co_binary)))": 271,
"opt(dictionary(hybrid(6,32),continued_fractions(dichotomic)))": 270,
"opt(dictionary(hybrid(6,32),heuristic(use_first(halving,approximation))))": 271,
"opt(dictionary(hybrid(6,32),heuristic(use_first(halving,delta_largest))))": 282,
"opt(dictionary(hybrid(6,64),continued_fractions(binary)))": 272,
"opt(dictionary(hybrid(6,64),continued_fractions(co_binary)))": 272,
"opt(dictionary(hybrid(6,64),continued_fractions(dichotomic)))": 268,
"opt(dictionary(hybrid(6,64),heuristic(use_first(halving,approximation))))": 272,
"opt(dictionary(hybrid(6,64),heuristic(use_first(halving,delta_largest))))": 310,
"opt(dictionary(hybrid(7,0),continued_fractions(binary)))": 381,
"opt(dictionary(hybrid(7,0),continued_fractions(co_binary)))": 381,
"opt(dictionary(hybrid(7,0),continued_fractions(dichotomic)))": 277,
"opt(dictionary(hybrid(7,0),heuristic(use_first(halving,approximation))))": 320,
"opt(dictionary(hybrid(7,0),heuristic(use_first(halving,delta_largest))))": 502,
"opt(dictionary(hybrid(7,16),continued_fractions(binary)))": 276,
"opt(dictionary(hybrid(7,16),continued_fractions(co_binary)))": 276,
"opt(dictionary(hybrid(7,16),continued_fractions(dichotomic)))": 276,
"opt(dictionary(hybrid(7,16),heuristic(use_first(halving,approximation))))": 276,
"opt(dictionary(hybrid(7,16),heuristic(use_first(halving,delta_largest))))": 276,
"opt(dictionary(hybrid(7,32),continued_fractions(binary)))": 271,
"opt(dictionary(hybrid(7,32),continued_fractions(co_binary)))": 271,
"opt(dictionary(hybrid(7,32),continued_fractions(dichotomic)))": 270,
"opt(dictionary(hybrid(7,32),heuristic(use_first(halving,approximation))))": 271,
"opt(dictionary(hybrid(7,32),heuristic(use_first(halving,delta_largest))))": 282,
"opt(dictionary(hybrid(7,64),continued_fractions(binary)))": 272,
"opt(dictionary(hybrid(7,64),continued_fractions(co_binary)))": 272,
"opt(dictionary(hybrid(7,64),continued_fractions(dichotomic)))": 268,
"opt(dictionary(hybrid(7,64),heuristic(use_first(halving,approximation))))": 272,
"opt(dictionary(hybrid(7,64),heuristic(use_first(halving,delta_largest))))": 310,
"opt(dictionary(hybrid(8,0),continued_fractions(binary)))": 381,
"opt(dictionary(hybrid(8,0),continued_fractions(co_binary)))": 381,
"opt(dictionary(hybrid(8,0),continued_fractions(dichotomic)))": 277,
"opt(dictionary(hybrid(8,0),heuristic(use_first(halving,approximation))))": 320,
"opt(dictionary(hybrid(8,0),heuristic(use_first(halving,delta_largest))))": 502,
"opt(dictionary(hybrid(8,16),continued_fractions(binary)))": 276,
"opt(dictionary(hybrid(8,16),continued_fractions(co_binary)))": 276,
"opt(dictionary(hybrid(8,16),continued_fractions(dichotomic)))": 276,
"opt(dictionary(hybrid(8,16),heuristic(use_first(halving,approximation))))": 276,
"opt(dictionary(hybrid(8,16),heuristic(use_first(halving,delta_largest))))": 276,
"opt(dictionary(hybrid(8,32),continued_fractions(binary)))": 271,
"opt(dictionary(hybrid(8,32),continued_fractions(co_binary)))": 271,
"opt(dictionary(hybrid(8,32),continued_fractions(dichotomic)))": 270,
"opt(dictionary(hybrid(8,32),heuristic(use_first(halving,approximation))))": 271,
"opt(dictionary(hybrid(8,32),heuristic(use_first(halving,delta_largest))))": 282,
"opt(dictionary(hybrid(8,64),continued_fractions(binary)))": 272,
"opt(dictionary(hybrid(8,64),continued_fractions(co_binary)))": 272,
"opt(dictionary(hybrid(8,64),continued_fractions(dichotomic)))": 268,
"opt(dictionary(hybrid(8,64),heuristic(use_first(halving,approximation))))": 272,
"opt(dictionary(hybrid(8,64),heuristic(use_first(halving,delta_largest))))": 310,
"opt(dictionary(run_length(0),continued_fractions(binary)))": 381,
"opt(dictionary(run_length(0),continued_fractions(co_binary)))": 381,
"opt(dictionary(run_length(0),continued_fractions(dichotomic)))": 268,
"opt(dictionary(run_length(0),heuristic(use_first(halving,approximation))))": 381,
"opt(dictionary(run_length(0),heuristic(use_first(halving,delta_largest))))": 502,
"opt(dictionary(run_length(128),continued_fractions(binary)))": 281,
"opt(dictionary(run_length(128),continued_fractions(co_binary)))": 281,
"opt(dictionary(run_length(128),continued_fractions(dichotomic)))": 267,
"opt(dictionary(run_length(128),heuristic(use_first(halving,approximation))))": 281,
"opt(dictionary(run_length(128),heuristic(use_first(halving,delta_largest))))": 371,
"opt(dictionary(run_length(16),continued_fractions(binary)))": 276,
"opt(dictionary(run_length(16),continued_fractions(co_binary)))": 276,
"opt(dictionary(run_length(16),continued_fractions(dichotomic)))": 276,
"opt(dictionary(run_length(16),heuristic(use_first(halving,approximation))))": 276,
"opt(dictionary(run_length(16),heuristic(use_first(halving,delta_largest))))": 276,
"opt(dictionary(run_length(32),continued_fractions(binary)))": 271,
"opt(dictionary(run_length(32),continued_fractions(co_binary)))": 271,
"opt(dictionary(run_length(32),continued_fractions(dichotomic)))": 270,
"opt(dictionary(run_length(32),heuristic(use_first(halving,approximation))))": 271,
"opt(dictionary(run_length(32),heuristic(use_first(halving,delta_largest))))": 281,
"opt(dictionary(run_length(64),continued_fractions(binary)))": 272,
"opt(dictionary(run_length(64),continued_fractions(co_binary)))": 272,
"opt(dictionary(run_length(64),continued_fractions(dichotomic)))": 268,
"opt(dictionary(run_length(64),heuristic(use_first(halving,approximation))))": 272,
"opt(dictionary(run_length(64),heuristic(use_first(halving,delta_largest))))": 310,
"opt(dictionary(sliding_window(128),continued_fractions(binary)))": 320,
"opt(dictionary(sliding_window(128),continued_fractions(co_binary)))": 320,
"opt(dictionary(sliding_window(128),continued_fractions(dichotomic)))": 279,
"opt(dictionary(sliding_window(128),heuristic(use_first(halving,approximation))))": 287,
"opt(dictionary(sliding_window(128),heuristic(use_first(halving,delta_largest))))": 380,
"opt(dictionary(sliding_window(16),continued_fractions(binary)))": 279,
"opt(dictionary(sliding_window(16),continued_fractions(co_binary)))": 279,
"opt(dictionary(sliding_window(16),continued_fractions(dichotomic)))": 277,
"opt(dictionary(sliding_window(16),heuristic(use_first(halving,approximation))))": 276,
"opt(dictionary(sliding_window(16),heuristic(use_first(halving,delta_largest))))": 280,
"opt(dictionary(sliding_window(32),continued_fractions(binary)))": 278,
"opt(dictionary(sliding_window(32),continued_fractions(co_binary)))": 278,
"opt(dictionary(sliding_window(32),continued_fractions(dichotomic)))": 276,
"opt(dictionary(sliding_window(32),heuristic(use_first(halving,approximation))))": 273,
"opt(dictionary(sliding_window(32),heuristic(use_first(halving,delta_largest))))": 290,
"opt(dictionary(sliding_window(4),continued_fractions(binary)))": 320,
"opt(dictionary(sliding_window(4),continued_fractions(co_binary)))": 320,
"opt(dictionary(sliding_window(4),continued_fractions(dichotomic)))": 320,
"opt(dictionary(sliding_window(4),heuristic(use_first(halving,approximation))))": 320,
"opt(dictionary(sliding_window(4),heuristic(use_first(halving,delta_largest))))": 320,
"opt(dictionary(sliding_window(64),continued_fractions(binary)))": 293,
"opt(dictionary(sliding_window(64),continued_fractions(co_binary)))": 293,
"opt(dictionary(sliding_window(64),continued_fractions(dichotomic)))": 276,
"opt(dictionary(sliding_window(64),heuristic(use_first(halving,approximation))))": 277,
"opt(dictionary(sliding_window(64),heuristic(use_first(halving,delta_largest))))": 318,
"opt(dictionary(sliding_window(8),continued_fractions(binary)))": 290,
"opt(dictionary(sliding_window(8),continued_fractions(co_binary)))": 290,
"opt(dictionary(sliding_window(8),continued_fractions(dichotomic)))": 290,
"opt(dictionary(sliding_window(8),heuristic(use_first(halving,approximation))))": 291,
"opt(dictionary(sliding_window(8),heuristic(use_first(halving,delta_largest))))": 291,
"opt(runs(continued_fractions(binary)))": 268,
"opt(runs(continued_fractions(co_binary)))": 268,
"opt(runs(continued_fractions(dichotomic)))": 266,
"opt(runs(heuristic(use_first(halving,approximation))))": 268,
"opt(runs(heuristic(use_first(halving,delta_largest))))": 270
} addchain-0.4.0/alg/ensemble/testdata/curve25519_scalar.golden 0000664 0000000 0000000 00000035321 15143052566 0023700 0 ustar 00root root 0000000 0000000 {
"opt(dictionary(hybrid(2,0),continued_fractions(binary)))": 289,
"opt(dictionary(hybrid(2,0),continued_fractions(co_binary)))": 289,
"opt(dictionary(hybrid(2,0),continued_fractions(dichotomic)))": 289,
"opt(dictionary(hybrid(2,0),heuristic(use_first(halving,approximation))))": 289,
"opt(dictionary(hybrid(2,0),heuristic(use_first(halving,delta_largest))))": 289,
"opt(dictionary(hybrid(2,16),continued_fractions(binary)))": 289,
"opt(dictionary(hybrid(2,16),continued_fractions(co_binary)))": 289,
"opt(dictionary(hybrid(2,16),continued_fractions(dichotomic)))": 289,
"opt(dictionary(hybrid(2,16),heuristic(use_first(halving,approximation))))": 289,
"opt(dictionary(hybrid(2,16),heuristic(use_first(halving,delta_largest))))": 289,
"opt(dictionary(hybrid(2,32),continued_fractions(binary)))": 289,
"opt(dictionary(hybrid(2,32),continued_fractions(co_binary)))": 289,
"opt(dictionary(hybrid(2,32),continued_fractions(dichotomic)))": 289,
"opt(dictionary(hybrid(2,32),heuristic(use_first(halving,approximation))))": 289,
"opt(dictionary(hybrid(2,32),heuristic(use_first(halving,delta_largest))))": 289,
"opt(dictionary(hybrid(2,64),continued_fractions(binary)))": 289,
"opt(dictionary(hybrid(2,64),continued_fractions(co_binary)))": 289,
"opt(dictionary(hybrid(2,64),continued_fractions(dichotomic)))": 289,
"opt(dictionary(hybrid(2,64),heuristic(use_first(halving,approximation))))": 289,
"opt(dictionary(hybrid(2,64),heuristic(use_first(halving,delta_largest))))": 289,
"opt(dictionary(hybrid(3,0),continued_fractions(binary)))": 287,
"opt(dictionary(hybrid(3,0),continued_fractions(co_binary)))": 287,
"opt(dictionary(hybrid(3,0),continued_fractions(dichotomic)))": 287,
"opt(dictionary(hybrid(3,0),heuristic(use_first(halving,approximation))))": 287,
"opt(dictionary(hybrid(3,0),heuristic(use_first(halving,delta_largest))))": 287,
"opt(dictionary(hybrid(3,16),continued_fractions(binary)))": 287,
"opt(dictionary(hybrid(3,16),continued_fractions(co_binary)))": 287,
"opt(dictionary(hybrid(3,16),continued_fractions(dichotomic)))": 287,
"opt(dictionary(hybrid(3,16),heuristic(use_first(halving,approximation))))": 287,
"opt(dictionary(hybrid(3,16),heuristic(use_first(halving,delta_largest))))": 287,
"opt(dictionary(hybrid(3,32),continued_fractions(binary)))": 287,
"opt(dictionary(hybrid(3,32),continued_fractions(co_binary)))": 287,
"opt(dictionary(hybrid(3,32),continued_fractions(dichotomic)))": 287,
"opt(dictionary(hybrid(3,32),heuristic(use_first(halving,approximation))))": 287,
"opt(dictionary(hybrid(3,32),heuristic(use_first(halving,delta_largest))))": 287,
"opt(dictionary(hybrid(3,64),continued_fractions(binary)))": 287,
"opt(dictionary(hybrid(3,64),continued_fractions(co_binary)))": 287,
"opt(dictionary(hybrid(3,64),continued_fractions(dichotomic)))": 287,
"opt(dictionary(hybrid(3,64),heuristic(use_first(halving,approximation))))": 287,
"opt(dictionary(hybrid(3,64),heuristic(use_first(halving,delta_largest))))": 287,
"opt(dictionary(hybrid(4,0),continued_fractions(binary)))": 283,
"opt(dictionary(hybrid(4,0),continued_fractions(co_binary)))": 283,
"opt(dictionary(hybrid(4,0),continued_fractions(dichotomic)))": 283,
"opt(dictionary(hybrid(4,0),heuristic(use_first(halving,approximation))))": 283,
"opt(dictionary(hybrid(4,0),heuristic(use_first(halving,delta_largest))))": 283,
"opt(dictionary(hybrid(4,16),continued_fractions(binary)))": 283,
"opt(dictionary(hybrid(4,16),continued_fractions(co_binary)))": 283,
"opt(dictionary(hybrid(4,16),continued_fractions(dichotomic)))": 283,
"opt(dictionary(hybrid(4,16),heuristic(use_first(halving,approximation))))": 283,
"opt(dictionary(hybrid(4,16),heuristic(use_first(halving,delta_largest))))": 283,
"opt(dictionary(hybrid(4,32),continued_fractions(binary)))": 283,
"opt(dictionary(hybrid(4,32),continued_fractions(co_binary)))": 283,
"opt(dictionary(hybrid(4,32),continued_fractions(dichotomic)))": 283,
"opt(dictionary(hybrid(4,32),heuristic(use_first(halving,approximation))))": 283,
"opt(dictionary(hybrid(4,32),heuristic(use_first(halving,delta_largest))))": 283,
"opt(dictionary(hybrid(4,64),continued_fractions(binary)))": 283,
"opt(dictionary(hybrid(4,64),continued_fractions(co_binary)))": 283,
"opt(dictionary(hybrid(4,64),continued_fractions(dichotomic)))": 283,
"opt(dictionary(hybrid(4,64),heuristic(use_first(halving,approximation))))": 283,
"opt(dictionary(hybrid(4,64),heuristic(use_first(halving,delta_largest))))": 283,
"opt(dictionary(hybrid(5,0),continued_fractions(binary)))": 285,
"opt(dictionary(hybrid(5,0),continued_fractions(co_binary)))": 285,
"opt(dictionary(hybrid(5,0),continued_fractions(dichotomic)))": 285,
"opt(dictionary(hybrid(5,0),heuristic(use_first(halving,approximation))))": 285,
"opt(dictionary(hybrid(5,0),heuristic(use_first(halving,delta_largest))))": 285,
"opt(dictionary(hybrid(5,16),continued_fractions(binary)))": 285,
"opt(dictionary(hybrid(5,16),continued_fractions(co_binary)))": 285,
"opt(dictionary(hybrid(5,16),continued_fractions(dichotomic)))": 285,
"opt(dictionary(hybrid(5,16),heuristic(use_first(halving,approximation))))": 285,
"opt(dictionary(hybrid(5,16),heuristic(use_first(halving,delta_largest))))": 285,
"opt(dictionary(hybrid(5,32),continued_fractions(binary)))": 285,
"opt(dictionary(hybrid(5,32),continued_fractions(co_binary)))": 285,
"opt(dictionary(hybrid(5,32),continued_fractions(dichotomic)))": 285,
"opt(dictionary(hybrid(5,32),heuristic(use_first(halving,approximation))))": 285,
"opt(dictionary(hybrid(5,32),heuristic(use_first(halving,delta_largest))))": 285,
"opt(dictionary(hybrid(5,64),continued_fractions(binary)))": 285,
"opt(dictionary(hybrid(5,64),continued_fractions(co_binary)))": 285,
"opt(dictionary(hybrid(5,64),continued_fractions(dichotomic)))": 285,
"opt(dictionary(hybrid(5,64),heuristic(use_first(halving,approximation))))": 285,
"opt(dictionary(hybrid(5,64),heuristic(use_first(halving,delta_largest))))": 285,
"opt(dictionary(hybrid(6,0),continued_fractions(binary)))": 285,
"opt(dictionary(hybrid(6,0),continued_fractions(co_binary)))": 285,
"opt(dictionary(hybrid(6,0),continued_fractions(dichotomic)))": 285,
"opt(dictionary(hybrid(6,0),heuristic(use_first(halving,approximation))))": 285,
"opt(dictionary(hybrid(6,0),heuristic(use_first(halving,delta_largest))))": 285,
"opt(dictionary(hybrid(6,16),continued_fractions(binary)))": 285,
"opt(dictionary(hybrid(6,16),continued_fractions(co_binary)))": 285,
"opt(dictionary(hybrid(6,16),continued_fractions(dichotomic)))": 285,
"opt(dictionary(hybrid(6,16),heuristic(use_first(halving,approximation))))": 285,
"opt(dictionary(hybrid(6,16),heuristic(use_first(halving,delta_largest))))": 285,
"opt(dictionary(hybrid(6,32),continued_fractions(binary)))": 285,
"opt(dictionary(hybrid(6,32),continued_fractions(co_binary)))": 285,
"opt(dictionary(hybrid(6,32),continued_fractions(dichotomic)))": 285,
"opt(dictionary(hybrid(6,32),heuristic(use_first(halving,approximation))))": 285,
"opt(dictionary(hybrid(6,32),heuristic(use_first(halving,delta_largest))))": 285,
"opt(dictionary(hybrid(6,64),continued_fractions(binary)))": 285,
"opt(dictionary(hybrid(6,64),continued_fractions(co_binary)))": 285,
"opt(dictionary(hybrid(6,64),continued_fractions(dichotomic)))": 285,
"opt(dictionary(hybrid(6,64),heuristic(use_first(halving,approximation))))": 285,
"opt(dictionary(hybrid(6,64),heuristic(use_first(halving,delta_largest))))": 285,
"opt(dictionary(hybrid(7,0),continued_fractions(binary)))": 284,
"opt(dictionary(hybrid(7,0),continued_fractions(co_binary)))": 284,
"opt(dictionary(hybrid(7,0),continued_fractions(dichotomic)))": 284,
"opt(dictionary(hybrid(7,0),heuristic(use_first(halving,approximation))))": 285,
"opt(dictionary(hybrid(7,0),heuristic(use_first(halving,delta_largest))))": 284,
"opt(dictionary(hybrid(7,16),continued_fractions(binary)))": 284,
"opt(dictionary(hybrid(7,16),continued_fractions(co_binary)))": 284,
"opt(dictionary(hybrid(7,16),continued_fractions(dichotomic)))": 284,
"opt(dictionary(hybrid(7,16),heuristic(use_first(halving,approximation))))": 285,
"opt(dictionary(hybrid(7,16),heuristic(use_first(halving,delta_largest))))": 284,
"opt(dictionary(hybrid(7,32),continued_fractions(binary)))": 284,
"opt(dictionary(hybrid(7,32),continued_fractions(co_binary)))": 284,
"opt(dictionary(hybrid(7,32),continued_fractions(dichotomic)))": 284,
"opt(dictionary(hybrid(7,32),heuristic(use_first(halving,approximation))))": 285,
"opt(dictionary(hybrid(7,32),heuristic(use_first(halving,delta_largest))))": 284,
"opt(dictionary(hybrid(7,64),continued_fractions(binary)))": 284,
"opt(dictionary(hybrid(7,64),continued_fractions(co_binary)))": 284,
"opt(dictionary(hybrid(7,64),continued_fractions(dichotomic)))": 284,
"opt(dictionary(hybrid(7,64),heuristic(use_first(halving,approximation))))": 285,
"opt(dictionary(hybrid(7,64),heuristic(use_first(halving,delta_largest))))": 284,
"opt(dictionary(hybrid(8,0),continued_fractions(binary)))": 283,
"opt(dictionary(hybrid(8,0),continued_fractions(co_binary)))": 283,
"opt(dictionary(hybrid(8,0),continued_fractions(dichotomic)))": 283,
"opt(dictionary(hybrid(8,0),heuristic(use_first(halving,approximation))))": 285,
"opt(dictionary(hybrid(8,0),heuristic(use_first(halving,delta_largest))))": 284,
"opt(dictionary(hybrid(8,16),continued_fractions(binary)))": 283,
"opt(dictionary(hybrid(8,16),continued_fractions(co_binary)))": 283,
"opt(dictionary(hybrid(8,16),continued_fractions(dichotomic)))": 283,
"opt(dictionary(hybrid(8,16),heuristic(use_first(halving,approximation))))": 285,
"opt(dictionary(hybrid(8,16),heuristic(use_first(halving,delta_largest))))": 284,
"opt(dictionary(hybrid(8,32),continued_fractions(binary)))": 283,
"opt(dictionary(hybrid(8,32),continued_fractions(co_binary)))": 283,
"opt(dictionary(hybrid(8,32),continued_fractions(dichotomic)))": 283,
"opt(dictionary(hybrid(8,32),heuristic(use_first(halving,approximation))))": 285,
"opt(dictionary(hybrid(8,32),heuristic(use_first(halving,delta_largest))))": 284,
"opt(dictionary(hybrid(8,64),continued_fractions(binary)))": 283,
"opt(dictionary(hybrid(8,64),continued_fractions(co_binary)))": 283,
"opt(dictionary(hybrid(8,64),continued_fractions(dichotomic)))": 283,
"opt(dictionary(hybrid(8,64),heuristic(use_first(halving,approximation))))": 285,
"opt(dictionary(hybrid(8,64),heuristic(use_first(halving,delta_largest))))": 284,
"opt(dictionary(run_length(0),continued_fractions(binary)))": 289,
"opt(dictionary(run_length(0),continued_fractions(co_binary)))": 289,
"opt(dictionary(run_length(0),continued_fractions(dichotomic)))": 289,
"opt(dictionary(run_length(0),heuristic(use_first(halving,approximation))))": 289,
"opt(dictionary(run_length(0),heuristic(use_first(halving,delta_largest))))": 289,
"opt(dictionary(run_length(128),continued_fractions(binary)))": 289,
"opt(dictionary(run_length(128),continued_fractions(co_binary)))": 289,
"opt(dictionary(run_length(128),continued_fractions(dichotomic)))": 289,
"opt(dictionary(run_length(128),heuristic(use_first(halving,approximation))))": 289,
"opt(dictionary(run_length(128),heuristic(use_first(halving,delta_largest))))": 289,
"opt(dictionary(run_length(16),continued_fractions(binary)))": 289,
"opt(dictionary(run_length(16),continued_fractions(co_binary)))": 289,
"opt(dictionary(run_length(16),continued_fractions(dichotomic)))": 289,
"opt(dictionary(run_length(16),heuristic(use_first(halving,approximation))))": 289,
"opt(dictionary(run_length(16),heuristic(use_first(halving,delta_largest))))": 289,
"opt(dictionary(run_length(32),continued_fractions(binary)))": 289,
"opt(dictionary(run_length(32),continued_fractions(co_binary)))": 289,
"opt(dictionary(run_length(32),continued_fractions(dichotomic)))": 289,
"opt(dictionary(run_length(32),heuristic(use_first(halving,approximation))))": 289,
"opt(dictionary(run_length(32),heuristic(use_first(halving,delta_largest))))": 289,
"opt(dictionary(run_length(64),continued_fractions(binary)))": 289,
"opt(dictionary(run_length(64),continued_fractions(co_binary)))": 289,
"opt(dictionary(run_length(64),continued_fractions(dichotomic)))": 289,
"opt(dictionary(run_length(64),heuristic(use_first(halving,approximation))))": 289,
"opt(dictionary(run_length(64),heuristic(use_first(halving,delta_largest))))": 289,
"opt(dictionary(sliding_window(128),continued_fractions(binary)))": 324,
"opt(dictionary(sliding_window(128),continued_fractions(co_binary)))": 443,
"opt(dictionary(sliding_window(128),continued_fractions(dichotomic)))": 344,
"opt(dictionary(sliding_window(128),heuristic(use_first(halving,approximation))))": 324,
"opt(dictionary(sliding_window(128),heuristic(use_first(halving,delta_largest))))": 374,
"opt(dictionary(sliding_window(16),continued_fractions(binary)))": 294,
"opt(dictionary(sliding_window(16),continued_fractions(co_binary)))": 294,
"opt(dictionary(sliding_window(16),continued_fractions(dichotomic)))": 294,
"opt(dictionary(sliding_window(16),heuristic(use_first(halving,approximation))))": 294,
"opt(dictionary(sliding_window(16),heuristic(use_first(halving,delta_largest))))": 292,
"opt(dictionary(sliding_window(32),continued_fractions(binary)))": 307,
"opt(dictionary(sliding_window(32),continued_fractions(co_binary)))": 307,
"opt(dictionary(sliding_window(32),continued_fractions(dichotomic)))": 307,
"opt(dictionary(sliding_window(32),heuristic(use_first(halving,approximation))))": 311,
"opt(dictionary(sliding_window(32),heuristic(use_first(halving,delta_largest))))": 310,
"opt(dictionary(sliding_window(4),continued_fractions(binary)))": 284,
"opt(dictionary(sliding_window(4),continued_fractions(co_binary)))": 284,
"opt(dictionary(sliding_window(4),continued_fractions(dichotomic)))": 284,
"opt(dictionary(sliding_window(4),heuristic(use_first(halving,approximation))))": 284,
"opt(dictionary(sliding_window(4),heuristic(use_first(halving,delta_largest))))": 284,
"opt(dictionary(sliding_window(64),continued_fractions(binary)))": 345,
"opt(dictionary(sliding_window(64),continued_fractions(co_binary)))": 346,
"opt(dictionary(sliding_window(64),continued_fractions(dichotomic)))": 344,
"opt(dictionary(sliding_window(64),heuristic(use_first(halving,approximation))))": 345,
"opt(dictionary(sliding_window(64),heuristic(use_first(halving,delta_largest))))": 345,
"opt(dictionary(sliding_window(8),continued_fractions(binary)))": 283,
"opt(dictionary(sliding_window(8),continued_fractions(co_binary)))": 283,
"opt(dictionary(sliding_window(8),continued_fractions(dichotomic)))": 283,
"opt(dictionary(sliding_window(8),heuristic(use_first(halving,approximation))))": 285,
"opt(dictionary(sliding_window(8),heuristic(use_first(halving,delta_largest))))": 284,
"opt(runs(continued_fractions(binary)))": 289,
"opt(runs(continued_fractions(co_binary)))": 289,
"opt(runs(continued_fractions(dichotomic)))": 289,
"opt(runs(heuristic(use_first(halving,approximation))))": 289,
"opt(runs(heuristic(use_first(halving,delta_largest))))": 289
} addchain-0.4.0/alg/ensemble/testdata/goldilocks_field.golden 0000664 0000000 0000000 00000035321 15143052566 0024116 0 ustar 00root root 0000000 0000000 {
"opt(dictionary(hybrid(2,0),continued_fractions(binary)))": 671,
"opt(dictionary(hybrid(2,0),continued_fractions(co_binary)))": 671,
"opt(dictionary(hybrid(2,0),continued_fractions(dichotomic)))": 462,
"opt(dictionary(hybrid(2,0),heuristic(use_first(halving,approximation))))": 561,
"opt(dictionary(hybrid(2,0),heuristic(use_first(halving,delta_largest))))": 668,
"opt(dictionary(hybrid(2,16),continued_fractions(binary)))": 490,
"opt(dictionary(hybrid(2,16),continued_fractions(co_binary)))": 490,
"opt(dictionary(hybrid(2,16),continued_fractions(dichotomic)))": 482,
"opt(dictionary(hybrid(2,16),heuristic(use_first(halving,approximation))))": 484,
"opt(dictionary(hybrid(2,16),heuristic(use_first(halving,delta_largest))))": 487,
"opt(dictionary(hybrid(2,32),continued_fractions(binary)))": 492,
"opt(dictionary(hybrid(2,32),continued_fractions(co_binary)))": 492,
"opt(dictionary(hybrid(2,32),continued_fractions(dichotomic)))": 470,
"opt(dictionary(hybrid(2,32),heuristic(use_first(halving,approximation))))": 478,
"opt(dictionary(hybrid(2,32),heuristic(use_first(halving,delta_largest))))": 489,
"opt(dictionary(hybrid(2,64),continued_fractions(binary)))": 473,
"opt(dictionary(hybrid(2,64),continued_fractions(co_binary)))": 473,
"opt(dictionary(hybrid(2,64),continued_fractions(dichotomic)))": 465,
"opt(dictionary(hybrid(2,64),heuristic(use_first(halving,approximation))))": 473,
"opt(dictionary(hybrid(2,64),heuristic(use_first(halving,delta_largest))))": 487,
"opt(dictionary(hybrid(3,0),continued_fractions(binary)))": 671,
"opt(dictionary(hybrid(3,0),continued_fractions(co_binary)))": 671,
"opt(dictionary(hybrid(3,0),continued_fractions(dichotomic)))": 462,
"opt(dictionary(hybrid(3,0),heuristic(use_first(halving,approximation))))": 561,
"opt(dictionary(hybrid(3,0),heuristic(use_first(halving,delta_largest))))": 668,
"opt(dictionary(hybrid(3,16),continued_fractions(binary)))": 490,
"opt(dictionary(hybrid(3,16),continued_fractions(co_binary)))": 490,
"opt(dictionary(hybrid(3,16),continued_fractions(dichotomic)))": 482,
"opt(dictionary(hybrid(3,16),heuristic(use_first(halving,approximation))))": 484,
"opt(dictionary(hybrid(3,16),heuristic(use_first(halving,delta_largest))))": 487,
"opt(dictionary(hybrid(3,32),continued_fractions(binary)))": 492,
"opt(dictionary(hybrid(3,32),continued_fractions(co_binary)))": 492,
"opt(dictionary(hybrid(3,32),continued_fractions(dichotomic)))": 470,
"opt(dictionary(hybrid(3,32),heuristic(use_first(halving,approximation))))": 478,
"opt(dictionary(hybrid(3,32),heuristic(use_first(halving,delta_largest))))": 489,
"opt(dictionary(hybrid(3,64),continued_fractions(binary)))": 473,
"opt(dictionary(hybrid(3,64),continued_fractions(co_binary)))": 473,
"opt(dictionary(hybrid(3,64),continued_fractions(dichotomic)))": 465,
"opt(dictionary(hybrid(3,64),heuristic(use_first(halving,approximation))))": 473,
"opt(dictionary(hybrid(3,64),heuristic(use_first(halving,delta_largest))))": 487,
"opt(dictionary(hybrid(4,0),continued_fractions(binary)))": 671,
"opt(dictionary(hybrid(4,0),continued_fractions(co_binary)))": 671,
"opt(dictionary(hybrid(4,0),continued_fractions(dichotomic)))": 462,
"opt(dictionary(hybrid(4,0),heuristic(use_first(halving,approximation))))": 561,
"opt(dictionary(hybrid(4,0),heuristic(use_first(halving,delta_largest))))": 668,
"opt(dictionary(hybrid(4,16),continued_fractions(binary)))": 490,
"opt(dictionary(hybrid(4,16),continued_fractions(co_binary)))": 490,
"opt(dictionary(hybrid(4,16),continued_fractions(dichotomic)))": 482,
"opt(dictionary(hybrid(4,16),heuristic(use_first(halving,approximation))))": 484,
"opt(dictionary(hybrid(4,16),heuristic(use_first(halving,delta_largest))))": 487,
"opt(dictionary(hybrid(4,32),continued_fractions(binary)))": 492,
"opt(dictionary(hybrid(4,32),continued_fractions(co_binary)))": 492,
"opt(dictionary(hybrid(4,32),continued_fractions(dichotomic)))": 470,
"opt(dictionary(hybrid(4,32),heuristic(use_first(halving,approximation))))": 478,
"opt(dictionary(hybrid(4,32),heuristic(use_first(halving,delta_largest))))": 489,
"opt(dictionary(hybrid(4,64),continued_fractions(binary)))": 473,
"opt(dictionary(hybrid(4,64),continued_fractions(co_binary)))": 473,
"opt(dictionary(hybrid(4,64),continued_fractions(dichotomic)))": 465,
"opt(dictionary(hybrid(4,64),heuristic(use_first(halving,approximation))))": 473,
"opt(dictionary(hybrid(4,64),heuristic(use_first(halving,delta_largest))))": 487,
"opt(dictionary(hybrid(5,0),continued_fractions(binary)))": 671,
"opt(dictionary(hybrid(5,0),continued_fractions(co_binary)))": 671,
"opt(dictionary(hybrid(5,0),continued_fractions(dichotomic)))": 462,
"opt(dictionary(hybrid(5,0),heuristic(use_first(halving,approximation))))": 561,
"opt(dictionary(hybrid(5,0),heuristic(use_first(halving,delta_largest))))": 668,
"opt(dictionary(hybrid(5,16),continued_fractions(binary)))": 490,
"opt(dictionary(hybrid(5,16),continued_fractions(co_binary)))": 490,
"opt(dictionary(hybrid(5,16),continued_fractions(dichotomic)))": 482,
"opt(dictionary(hybrid(5,16),heuristic(use_first(halving,approximation))))": 484,
"opt(dictionary(hybrid(5,16),heuristic(use_first(halving,delta_largest))))": 487,
"opt(dictionary(hybrid(5,32),continued_fractions(binary)))": 492,
"opt(dictionary(hybrid(5,32),continued_fractions(co_binary)))": 492,
"opt(dictionary(hybrid(5,32),continued_fractions(dichotomic)))": 470,
"opt(dictionary(hybrid(5,32),heuristic(use_first(halving,approximation))))": 478,
"opt(dictionary(hybrid(5,32),heuristic(use_first(halving,delta_largest))))": 489,
"opt(dictionary(hybrid(5,64),continued_fractions(binary)))": 473,
"opt(dictionary(hybrid(5,64),continued_fractions(co_binary)))": 473,
"opt(dictionary(hybrid(5,64),continued_fractions(dichotomic)))": 465,
"opt(dictionary(hybrid(5,64),heuristic(use_first(halving,approximation))))": 473,
"opt(dictionary(hybrid(5,64),heuristic(use_first(halving,delta_largest))))": 487,
"opt(dictionary(hybrid(6,0),continued_fractions(binary)))": 671,
"opt(dictionary(hybrid(6,0),continued_fractions(co_binary)))": 671,
"opt(dictionary(hybrid(6,0),continued_fractions(dichotomic)))": 462,
"opt(dictionary(hybrid(6,0),heuristic(use_first(halving,approximation))))": 561,
"opt(dictionary(hybrid(6,0),heuristic(use_first(halving,delta_largest))))": 668,
"opt(dictionary(hybrid(6,16),continued_fractions(binary)))": 490,
"opt(dictionary(hybrid(6,16),continued_fractions(co_binary)))": 490,
"opt(dictionary(hybrid(6,16),continued_fractions(dichotomic)))": 482,
"opt(dictionary(hybrid(6,16),heuristic(use_first(halving,approximation))))": 484,
"opt(dictionary(hybrid(6,16),heuristic(use_first(halving,delta_largest))))": 487,
"opt(dictionary(hybrid(6,32),continued_fractions(binary)))": 492,
"opt(dictionary(hybrid(6,32),continued_fractions(co_binary)))": 492,
"opt(dictionary(hybrid(6,32),continued_fractions(dichotomic)))": 470,
"opt(dictionary(hybrid(6,32),heuristic(use_first(halving,approximation))))": 478,
"opt(dictionary(hybrid(6,32),heuristic(use_first(halving,delta_largest))))": 489,
"opt(dictionary(hybrid(6,64),continued_fractions(binary)))": 473,
"opt(dictionary(hybrid(6,64),continued_fractions(co_binary)))": 473,
"opt(dictionary(hybrid(6,64),continued_fractions(dichotomic)))": 465,
"opt(dictionary(hybrid(6,64),heuristic(use_first(halving,approximation))))": 473,
"opt(dictionary(hybrid(6,64),heuristic(use_first(halving,delta_largest))))": 487,
"opt(dictionary(hybrid(7,0),continued_fractions(binary)))": 671,
"opt(dictionary(hybrid(7,0),continued_fractions(co_binary)))": 671,
"opt(dictionary(hybrid(7,0),continued_fractions(dichotomic)))": 462,
"opt(dictionary(hybrid(7,0),heuristic(use_first(halving,approximation))))": 561,
"opt(dictionary(hybrid(7,0),heuristic(use_first(halving,delta_largest))))": 668,
"opt(dictionary(hybrid(7,16),continued_fractions(binary)))": 490,
"opt(dictionary(hybrid(7,16),continued_fractions(co_binary)))": 490,
"opt(dictionary(hybrid(7,16),continued_fractions(dichotomic)))": 482,
"opt(dictionary(hybrid(7,16),heuristic(use_first(halving,approximation))))": 484,
"opt(dictionary(hybrid(7,16),heuristic(use_first(halving,delta_largest))))": 487,
"opt(dictionary(hybrid(7,32),continued_fractions(binary)))": 492,
"opt(dictionary(hybrid(7,32),continued_fractions(co_binary)))": 492,
"opt(dictionary(hybrid(7,32),continued_fractions(dichotomic)))": 470,
"opt(dictionary(hybrid(7,32),heuristic(use_first(halving,approximation))))": 478,
"opt(dictionary(hybrid(7,32),heuristic(use_first(halving,delta_largest))))": 489,
"opt(dictionary(hybrid(7,64),continued_fractions(binary)))": 473,
"opt(dictionary(hybrid(7,64),continued_fractions(co_binary)))": 473,
"opt(dictionary(hybrid(7,64),continued_fractions(dichotomic)))": 465,
"opt(dictionary(hybrid(7,64),heuristic(use_first(halving,approximation))))": 473,
"opt(dictionary(hybrid(7,64),heuristic(use_first(halving,delta_largest))))": 487,
"opt(dictionary(hybrid(8,0),continued_fractions(binary)))": 671,
"opt(dictionary(hybrid(8,0),continued_fractions(co_binary)))": 671,
"opt(dictionary(hybrid(8,0),continued_fractions(dichotomic)))": 462,
"opt(dictionary(hybrid(8,0),heuristic(use_first(halving,approximation))))": 561,
"opt(dictionary(hybrid(8,0),heuristic(use_first(halving,delta_largest))))": 668,
"opt(dictionary(hybrid(8,16),continued_fractions(binary)))": 490,
"opt(dictionary(hybrid(8,16),continued_fractions(co_binary)))": 490,
"opt(dictionary(hybrid(8,16),continued_fractions(dichotomic)))": 482,
"opt(dictionary(hybrid(8,16),heuristic(use_first(halving,approximation))))": 484,
"opt(dictionary(hybrid(8,16),heuristic(use_first(halving,delta_largest))))": 487,
"opt(dictionary(hybrid(8,32),continued_fractions(binary)))": 492,
"opt(dictionary(hybrid(8,32),continued_fractions(co_binary)))": 492,
"opt(dictionary(hybrid(8,32),continued_fractions(dichotomic)))": 470,
"opt(dictionary(hybrid(8,32),heuristic(use_first(halving,approximation))))": 478,
"opt(dictionary(hybrid(8,32),heuristic(use_first(halving,delta_largest))))": 489,
"opt(dictionary(hybrid(8,64),continued_fractions(binary)))": 473,
"opt(dictionary(hybrid(8,64),continued_fractions(co_binary)))": 473,
"opt(dictionary(hybrid(8,64),continued_fractions(dichotomic)))": 465,
"opt(dictionary(hybrid(8,64),heuristic(use_first(halving,approximation))))": 473,
"opt(dictionary(hybrid(8,64),heuristic(use_first(halving,delta_largest))))": 487,
"opt(dictionary(run_length(0),continued_fractions(binary)))": 671,
"opt(dictionary(run_length(0),continued_fractions(co_binary)))": 671,
"opt(dictionary(run_length(0),continued_fractions(dichotomic)))": 462,
"opt(dictionary(run_length(0),heuristic(use_first(halving,approximation))))": 561,
"opt(dictionary(run_length(0),heuristic(use_first(halving,delta_largest))))": 668,
"opt(dictionary(run_length(128),continued_fractions(binary)))": 464,
"opt(dictionary(run_length(128),continued_fractions(co_binary)))": 464,
"opt(dictionary(run_length(128),continued_fractions(dichotomic)))": 463,
"opt(dictionary(run_length(128),heuristic(use_first(halving,approximation))))": 464,
"opt(dictionary(run_length(128),heuristic(use_first(halving,delta_largest))))": 502,
"opt(dictionary(run_length(16),continued_fractions(binary)))": 490,
"opt(dictionary(run_length(16),continued_fractions(co_binary)))": 490,
"opt(dictionary(run_length(16),continued_fractions(dichotomic)))": 482,
"opt(dictionary(run_length(16),heuristic(use_first(halving,approximation))))": 484,
"opt(dictionary(run_length(16),heuristic(use_first(halving,delta_largest))))": 487,
"opt(dictionary(run_length(32),continued_fractions(binary)))": 492,
"opt(dictionary(run_length(32),continued_fractions(co_binary)))": 492,
"opt(dictionary(run_length(32),continued_fractions(dichotomic)))": 470,
"opt(dictionary(run_length(32),heuristic(use_first(halving,approximation))))": 478,
"opt(dictionary(run_length(32),heuristic(use_first(halving,delta_largest))))": 489,
"opt(dictionary(run_length(64),continued_fractions(binary)))": 473,
"opt(dictionary(run_length(64),continued_fractions(co_binary)))": 473,
"opt(dictionary(run_length(64),continued_fractions(dichotomic)))": 465,
"opt(dictionary(run_length(64),heuristic(use_first(halving,approximation))))": 473,
"opt(dictionary(run_length(64),heuristic(use_first(halving,delta_largest))))": 487,
"opt(dictionary(sliding_window(128),continued_fractions(binary)))": 515,
"opt(dictionary(sliding_window(128),continued_fractions(co_binary)))": 515,
"opt(dictionary(sliding_window(128),continued_fractions(dichotomic)))": 468,
"opt(dictionary(sliding_window(128),heuristic(use_first(halving,approximation))))": 472,
"opt(dictionary(sliding_window(128),heuristic(use_first(halving,delta_largest))))": 484,
"opt(dictionary(sliding_window(16),continued_fractions(binary)))": 489,
"opt(dictionary(sliding_window(16),continued_fractions(co_binary)))": 489,
"opt(dictionary(sliding_window(16),continued_fractions(dichotomic)))": 481,
"opt(dictionary(sliding_window(16),heuristic(use_first(halving,approximation))))": 483,
"opt(dictionary(sliding_window(16),heuristic(use_first(halving,delta_largest))))": 486,
"opt(dictionary(sliding_window(32),continued_fractions(binary)))": 491,
"opt(dictionary(sliding_window(32),continued_fractions(co_binary)))": 491,
"opt(dictionary(sliding_window(32),continued_fractions(dichotomic)))": 469,
"opt(dictionary(sliding_window(32),heuristic(use_first(halving,approximation))))": 477,
"opt(dictionary(sliding_window(32),heuristic(use_first(halving,delta_largest))))": 488,
"opt(dictionary(sliding_window(4),continued_fractions(binary)))": 561,
"opt(dictionary(sliding_window(4),continued_fractions(co_binary)))": 561,
"opt(dictionary(sliding_window(4),continued_fractions(dichotomic)))": 561,
"opt(dictionary(sliding_window(4),heuristic(use_first(halving,approximation))))": 561,
"opt(dictionary(sliding_window(4),heuristic(use_first(halving,delta_largest))))": 561,
"opt(dictionary(sliding_window(64),continued_fractions(binary)))": 487,
"opt(dictionary(sliding_window(64),continued_fractions(co_binary)))": 487,
"opt(dictionary(sliding_window(64),continued_fractions(dichotomic)))": 465,
"opt(dictionary(sliding_window(64),heuristic(use_first(halving,approximation))))": 473,
"opt(dictionary(sliding_window(64),heuristic(use_first(halving,delta_largest))))": 487,
"opt(dictionary(sliding_window(8),continued_fractions(binary)))": 509,
"opt(dictionary(sliding_window(8),continued_fractions(co_binary)))": 509,
"opt(dictionary(sliding_window(8),continued_fractions(dichotomic)))": 507,
"opt(dictionary(sliding_window(8),heuristic(use_first(halving,approximation))))": 507,
"opt(dictionary(sliding_window(8),heuristic(use_first(halving,delta_largest))))": 507,
"opt(runs(continued_fractions(binary)))": 462,
"opt(runs(continued_fractions(co_binary)))": 462,
"opt(runs(continued_fractions(dichotomic)))": 461,
"opt(runs(heuristic(use_first(halving,approximation))))": 460,
"opt(runs(heuristic(use_first(halving,delta_largest))))": 461
} addchain-0.4.0/alg/ensemble/testdata/p192_field.golden 0000664 0000000 0000000 00000035321 15143052566 0022457 0 ustar 00root root 0000000 0000000 {
"opt(dictionary(hybrid(2,0),continued_fractions(binary)))": 217,
"opt(dictionary(hybrid(2,0),continued_fractions(co_binary)))": 217,
"opt(dictionary(hybrid(2,0),continued_fractions(dichotomic)))": 203,
"opt(dictionary(hybrid(2,0),heuristic(use_first(halving,approximation))))": 217,
"opt(dictionary(hybrid(2,0),heuristic(use_first(halving,delta_largest))))": 257,
"opt(dictionary(hybrid(2,16),continued_fractions(binary)))": 218,
"opt(dictionary(hybrid(2,16),continued_fractions(co_binary)))": 218,
"opt(dictionary(hybrid(2,16),continued_fractions(dichotomic)))": 210,
"opt(dictionary(hybrid(2,16),heuristic(use_first(halving,approximation))))": 212,
"opt(dictionary(hybrid(2,16),heuristic(use_first(halving,delta_largest))))": 215,
"opt(dictionary(hybrid(2,32),continued_fractions(binary)))": 228,
"opt(dictionary(hybrid(2,32),continued_fractions(co_binary)))": 228,
"opt(dictionary(hybrid(2,32),continued_fractions(dichotomic)))": 206,
"opt(dictionary(hybrid(2,32),heuristic(use_first(halving,approximation))))": 214,
"opt(dictionary(hybrid(2,32),heuristic(use_first(halving,delta_largest))))": 225,
"opt(dictionary(hybrid(2,64),continued_fractions(binary)))": 257,
"opt(dictionary(hybrid(2,64),continued_fractions(co_binary)))": 257,
"opt(dictionary(hybrid(2,64),continued_fractions(dichotomic)))": 205,
"opt(dictionary(hybrid(2,64),heuristic(use_first(halving,approximation))))": 227,
"opt(dictionary(hybrid(2,64),heuristic(use_first(halving,delta_largest))))": 254,
"opt(dictionary(hybrid(3,0),continued_fractions(binary)))": 217,
"opt(dictionary(hybrid(3,0),continued_fractions(co_binary)))": 217,
"opt(dictionary(hybrid(3,0),continued_fractions(dichotomic)))": 203,
"opt(dictionary(hybrid(3,0),heuristic(use_first(halving,approximation))))": 217,
"opt(dictionary(hybrid(3,0),heuristic(use_first(halving,delta_largest))))": 257,
"opt(dictionary(hybrid(3,16),continued_fractions(binary)))": 218,
"opt(dictionary(hybrid(3,16),continued_fractions(co_binary)))": 218,
"opt(dictionary(hybrid(3,16),continued_fractions(dichotomic)))": 210,
"opt(dictionary(hybrid(3,16),heuristic(use_first(halving,approximation))))": 212,
"opt(dictionary(hybrid(3,16),heuristic(use_first(halving,delta_largest))))": 215,
"opt(dictionary(hybrid(3,32),continued_fractions(binary)))": 228,
"opt(dictionary(hybrid(3,32),continued_fractions(co_binary)))": 228,
"opt(dictionary(hybrid(3,32),continued_fractions(dichotomic)))": 206,
"opt(dictionary(hybrid(3,32),heuristic(use_first(halving,approximation))))": 214,
"opt(dictionary(hybrid(3,32),heuristic(use_first(halving,delta_largest))))": 225,
"opt(dictionary(hybrid(3,64),continued_fractions(binary)))": 257,
"opt(dictionary(hybrid(3,64),continued_fractions(co_binary)))": 257,
"opt(dictionary(hybrid(3,64),continued_fractions(dichotomic)))": 205,
"opt(dictionary(hybrid(3,64),heuristic(use_first(halving,approximation))))": 227,
"opt(dictionary(hybrid(3,64),heuristic(use_first(halving,delta_largest))))": 254,
"opt(dictionary(hybrid(4,0),continued_fractions(binary)))": 217,
"opt(dictionary(hybrid(4,0),continued_fractions(co_binary)))": 217,
"opt(dictionary(hybrid(4,0),continued_fractions(dichotomic)))": 203,
"opt(dictionary(hybrid(4,0),heuristic(use_first(halving,approximation))))": 217,
"opt(dictionary(hybrid(4,0),heuristic(use_first(halving,delta_largest))))": 257,
"opt(dictionary(hybrid(4,16),continued_fractions(binary)))": 218,
"opt(dictionary(hybrid(4,16),continued_fractions(co_binary)))": 218,
"opt(dictionary(hybrid(4,16),continued_fractions(dichotomic)))": 210,
"opt(dictionary(hybrid(4,16),heuristic(use_first(halving,approximation))))": 212,
"opt(dictionary(hybrid(4,16),heuristic(use_first(halving,delta_largest))))": 215,
"opt(dictionary(hybrid(4,32),continued_fractions(binary)))": 228,
"opt(dictionary(hybrid(4,32),continued_fractions(co_binary)))": 228,
"opt(dictionary(hybrid(4,32),continued_fractions(dichotomic)))": 206,
"opt(dictionary(hybrid(4,32),heuristic(use_first(halving,approximation))))": 214,
"opt(dictionary(hybrid(4,32),heuristic(use_first(halving,delta_largest))))": 225,
"opt(dictionary(hybrid(4,64),continued_fractions(binary)))": 257,
"opt(dictionary(hybrid(4,64),continued_fractions(co_binary)))": 257,
"opt(dictionary(hybrid(4,64),continued_fractions(dichotomic)))": 205,
"opt(dictionary(hybrid(4,64),heuristic(use_first(halving,approximation))))": 227,
"opt(dictionary(hybrid(4,64),heuristic(use_first(halving,delta_largest))))": 254,
"opt(dictionary(hybrid(5,0),continued_fractions(binary)))": 217,
"opt(dictionary(hybrid(5,0),continued_fractions(co_binary)))": 217,
"opt(dictionary(hybrid(5,0),continued_fractions(dichotomic)))": 203,
"opt(dictionary(hybrid(5,0),heuristic(use_first(halving,approximation))))": 217,
"opt(dictionary(hybrid(5,0),heuristic(use_first(halving,delta_largest))))": 257,
"opt(dictionary(hybrid(5,16),continued_fractions(binary)))": 218,
"opt(dictionary(hybrid(5,16),continued_fractions(co_binary)))": 218,
"opt(dictionary(hybrid(5,16),continued_fractions(dichotomic)))": 210,
"opt(dictionary(hybrid(5,16),heuristic(use_first(halving,approximation))))": 212,
"opt(dictionary(hybrid(5,16),heuristic(use_first(halving,delta_largest))))": 215,
"opt(dictionary(hybrid(5,32),continued_fractions(binary)))": 228,
"opt(dictionary(hybrid(5,32),continued_fractions(co_binary)))": 228,
"opt(dictionary(hybrid(5,32),continued_fractions(dichotomic)))": 206,
"opt(dictionary(hybrid(5,32),heuristic(use_first(halving,approximation))))": 214,
"opt(dictionary(hybrid(5,32),heuristic(use_first(halving,delta_largest))))": 225,
"opt(dictionary(hybrid(5,64),continued_fractions(binary)))": 257,
"opt(dictionary(hybrid(5,64),continued_fractions(co_binary)))": 257,
"opt(dictionary(hybrid(5,64),continued_fractions(dichotomic)))": 205,
"opt(dictionary(hybrid(5,64),heuristic(use_first(halving,approximation))))": 227,
"opt(dictionary(hybrid(5,64),heuristic(use_first(halving,delta_largest))))": 254,
"opt(dictionary(hybrid(6,0),continued_fractions(binary)))": 217,
"opt(dictionary(hybrid(6,0),continued_fractions(co_binary)))": 217,
"opt(dictionary(hybrid(6,0),continued_fractions(dichotomic)))": 203,
"opt(dictionary(hybrid(6,0),heuristic(use_first(halving,approximation))))": 217,
"opt(dictionary(hybrid(6,0),heuristic(use_first(halving,delta_largest))))": 257,
"opt(dictionary(hybrid(6,16),continued_fractions(binary)))": 218,
"opt(dictionary(hybrid(6,16),continued_fractions(co_binary)))": 218,
"opt(dictionary(hybrid(6,16),continued_fractions(dichotomic)))": 210,
"opt(dictionary(hybrid(6,16),heuristic(use_first(halving,approximation))))": 212,
"opt(dictionary(hybrid(6,16),heuristic(use_first(halving,delta_largest))))": 215,
"opt(dictionary(hybrid(6,32),continued_fractions(binary)))": 228,
"opt(dictionary(hybrid(6,32),continued_fractions(co_binary)))": 228,
"opt(dictionary(hybrid(6,32),continued_fractions(dichotomic)))": 206,
"opt(dictionary(hybrid(6,32),heuristic(use_first(halving,approximation))))": 214,
"opt(dictionary(hybrid(6,32),heuristic(use_first(halving,delta_largest))))": 225,
"opt(dictionary(hybrid(6,64),continued_fractions(binary)))": 257,
"opt(dictionary(hybrid(6,64),continued_fractions(co_binary)))": 257,
"opt(dictionary(hybrid(6,64),continued_fractions(dichotomic)))": 205,
"opt(dictionary(hybrid(6,64),heuristic(use_first(halving,approximation))))": 227,
"opt(dictionary(hybrid(6,64),heuristic(use_first(halving,delta_largest))))": 254,
"opt(dictionary(hybrid(7,0),continued_fractions(binary)))": 217,
"opt(dictionary(hybrid(7,0),continued_fractions(co_binary)))": 217,
"opt(dictionary(hybrid(7,0),continued_fractions(dichotomic)))": 203,
"opt(dictionary(hybrid(7,0),heuristic(use_first(halving,approximation))))": 217,
"opt(dictionary(hybrid(7,0),heuristic(use_first(halving,delta_largest))))": 257,
"opt(dictionary(hybrid(7,16),continued_fractions(binary)))": 218,
"opt(dictionary(hybrid(7,16),continued_fractions(co_binary)))": 218,
"opt(dictionary(hybrid(7,16),continued_fractions(dichotomic)))": 210,
"opt(dictionary(hybrid(7,16),heuristic(use_first(halving,approximation))))": 212,
"opt(dictionary(hybrid(7,16),heuristic(use_first(halving,delta_largest))))": 215,
"opt(dictionary(hybrid(7,32),continued_fractions(binary)))": 228,
"opt(dictionary(hybrid(7,32),continued_fractions(co_binary)))": 228,
"opt(dictionary(hybrid(7,32),continued_fractions(dichotomic)))": 206,
"opt(dictionary(hybrid(7,32),heuristic(use_first(halving,approximation))))": 214,
"opt(dictionary(hybrid(7,32),heuristic(use_first(halving,delta_largest))))": 225,
"opt(dictionary(hybrid(7,64),continued_fractions(binary)))": 257,
"opt(dictionary(hybrid(7,64),continued_fractions(co_binary)))": 257,
"opt(dictionary(hybrid(7,64),continued_fractions(dichotomic)))": 205,
"opt(dictionary(hybrid(7,64),heuristic(use_first(halving,approximation))))": 227,
"opt(dictionary(hybrid(7,64),heuristic(use_first(halving,delta_largest))))": 254,
"opt(dictionary(hybrid(8,0),continued_fractions(binary)))": 217,
"opt(dictionary(hybrid(8,0),continued_fractions(co_binary)))": 217,
"opt(dictionary(hybrid(8,0),continued_fractions(dichotomic)))": 203,
"opt(dictionary(hybrid(8,0),heuristic(use_first(halving,approximation))))": 217,
"opt(dictionary(hybrid(8,0),heuristic(use_first(halving,delta_largest))))": 257,
"opt(dictionary(hybrid(8,16),continued_fractions(binary)))": 218,
"opt(dictionary(hybrid(8,16),continued_fractions(co_binary)))": 218,
"opt(dictionary(hybrid(8,16),continued_fractions(dichotomic)))": 210,
"opt(dictionary(hybrid(8,16),heuristic(use_first(halving,approximation))))": 212,
"opt(dictionary(hybrid(8,16),heuristic(use_first(halving,delta_largest))))": 215,
"opt(dictionary(hybrid(8,32),continued_fractions(binary)))": 228,
"opt(dictionary(hybrid(8,32),continued_fractions(co_binary)))": 228,
"opt(dictionary(hybrid(8,32),continued_fractions(dichotomic)))": 206,
"opt(dictionary(hybrid(8,32),heuristic(use_first(halving,approximation))))": 214,
"opt(dictionary(hybrid(8,32),heuristic(use_first(halving,delta_largest))))": 225,
"opt(dictionary(hybrid(8,64),continued_fractions(binary)))": 257,
"opt(dictionary(hybrid(8,64),continued_fractions(co_binary)))": 257,
"opt(dictionary(hybrid(8,64),continued_fractions(dichotomic)))": 205,
"opt(dictionary(hybrid(8,64),heuristic(use_first(halving,approximation))))": 227,
"opt(dictionary(hybrid(8,64),heuristic(use_first(halving,delta_largest))))": 254,
"opt(dictionary(run_length(0),continued_fractions(binary)))": 217,
"opt(dictionary(run_length(0),continued_fractions(co_binary)))": 217,
"opt(dictionary(run_length(0),continued_fractions(dichotomic)))": 203,
"opt(dictionary(run_length(0),heuristic(use_first(halving,approximation))))": 217,
"opt(dictionary(run_length(0),heuristic(use_first(halving,delta_largest))))": 257,
"opt(dictionary(run_length(128),continued_fractions(binary)))": 217,
"opt(dictionary(run_length(128),continued_fractions(co_binary)))": 217,
"opt(dictionary(run_length(128),continued_fractions(dichotomic)))": 203,
"opt(dictionary(run_length(128),heuristic(use_first(halving,approximation))))": 217,
"opt(dictionary(run_length(128),heuristic(use_first(halving,delta_largest))))": 257,
"opt(dictionary(run_length(16),continued_fractions(binary)))": 218,
"opt(dictionary(run_length(16),continued_fractions(co_binary)))": 218,
"opt(dictionary(run_length(16),continued_fractions(dichotomic)))": 210,
"opt(dictionary(run_length(16),heuristic(use_first(halving,approximation))))": 212,
"opt(dictionary(run_length(16),heuristic(use_first(halving,delta_largest))))": 215,
"opt(dictionary(run_length(32),continued_fractions(binary)))": 228,
"opt(dictionary(run_length(32),continued_fractions(co_binary)))": 228,
"opt(dictionary(run_length(32),continued_fractions(dichotomic)))": 206,
"opt(dictionary(run_length(32),heuristic(use_first(halving,approximation))))": 214,
"opt(dictionary(run_length(32),heuristic(use_first(halving,delta_largest))))": 225,
"opt(dictionary(run_length(64),continued_fractions(binary)))": 257,
"opt(dictionary(run_length(64),continued_fractions(co_binary)))": 257,
"opt(dictionary(run_length(64),continued_fractions(dichotomic)))": 205,
"opt(dictionary(run_length(64),heuristic(use_first(halving,approximation))))": 227,
"opt(dictionary(run_length(64),heuristic(use_first(halving,delta_largest))))": 254,
"opt(dictionary(sliding_window(128),continued_fractions(binary)))": 217,
"opt(dictionary(sliding_window(128),continued_fractions(co_binary)))": 217,
"opt(dictionary(sliding_window(128),continued_fractions(dichotomic)))": 205,
"opt(dictionary(sliding_window(128),heuristic(use_first(halving,approximation))))": 226,
"opt(dictionary(sliding_window(128),heuristic(use_first(halving,delta_largest))))": 253,
"opt(dictionary(sliding_window(16),continued_fractions(binary)))": 217,
"opt(dictionary(sliding_window(16),continued_fractions(co_binary)))": 217,
"opt(dictionary(sliding_window(16),continued_fractions(dichotomic)))": 209,
"opt(dictionary(sliding_window(16),heuristic(use_first(halving,approximation))))": 211,
"opt(dictionary(sliding_window(16),heuristic(use_first(halving,delta_largest))))": 214,
"opt(dictionary(sliding_window(32),continued_fractions(binary)))": 227,
"opt(dictionary(sliding_window(32),continued_fractions(co_binary)))": 227,
"opt(dictionary(sliding_window(32),continued_fractions(dichotomic)))": 205,
"opt(dictionary(sliding_window(32),heuristic(use_first(halving,approximation))))": 213,
"opt(dictionary(sliding_window(32),heuristic(use_first(halving,delta_largest))))": 224,
"opt(dictionary(sliding_window(4),continued_fractions(binary)))": 241,
"opt(dictionary(sliding_window(4),continued_fractions(co_binary)))": 241,
"opt(dictionary(sliding_window(4),continued_fractions(dichotomic)))": 241,
"opt(dictionary(sliding_window(4),heuristic(use_first(halving,approximation))))": 241,
"opt(dictionary(sliding_window(4),heuristic(use_first(halving,delta_largest))))": 241,
"opt(dictionary(sliding_window(64),continued_fractions(binary)))": 256,
"opt(dictionary(sliding_window(64),continued_fractions(co_binary)))": 256,
"opt(dictionary(sliding_window(64),continued_fractions(dichotomic)))": 204,
"opt(dictionary(sliding_window(64),heuristic(use_first(halving,approximation))))": 226,
"opt(dictionary(sliding_window(64),heuristic(use_first(halving,delta_largest))))": 253,
"opt(dictionary(sliding_window(8),continued_fractions(binary)))": 221,
"opt(dictionary(sliding_window(8),continued_fractions(co_binary)))": 221,
"opt(dictionary(sliding_window(8),continued_fractions(dichotomic)))": 219,
"opt(dictionary(sliding_window(8),heuristic(use_first(halving,approximation))))": 219,
"opt(dictionary(sliding_window(8),heuristic(use_first(halving,delta_largest))))": 219,
"opt(runs(continued_fractions(binary)))": 203,
"opt(runs(continued_fractions(co_binary)))": 203,
"opt(runs(continued_fractions(dichotomic)))": 203,
"opt(runs(heuristic(use_first(halving,approximation))))": 204,
"opt(runs(heuristic(use_first(halving,delta_largest))))": 206
} addchain-0.4.0/alg/ensemble/testdata/p2213_field.golden 0000664 0000000 0000000 00000035321 15143052566 0022533 0 ustar 00root root 0000000 0000000 {
"opt(dictionary(hybrid(2,0),continued_fractions(binary)))": 330,
"opt(dictionary(hybrid(2,0),continued_fractions(co_binary)))": 330,
"opt(dictionary(hybrid(2,0),continued_fractions(dichotomic)))": 232,
"opt(dictionary(hybrid(2,0),heuristic(use_first(halving,approximation))))": 330,
"opt(dictionary(hybrid(2,0),heuristic(use_first(halving,delta_largest))))": 435,
"opt(dictionary(hybrid(2,16),continued_fractions(binary)))": 239,
"opt(dictionary(hybrid(2,16),continued_fractions(co_binary)))": 239,
"opt(dictionary(hybrid(2,16),continued_fractions(dichotomic)))": 239,
"opt(dictionary(hybrid(2,16),heuristic(use_first(halving,approximation))))": 239,
"opt(dictionary(hybrid(2,16),heuristic(use_first(halving,delta_largest))))": 239,
"opt(dictionary(hybrid(2,32),continued_fractions(binary)))": 235,
"opt(dictionary(hybrid(2,32),continued_fractions(co_binary)))": 235,
"opt(dictionary(hybrid(2,32),continued_fractions(dichotomic)))": 234,
"opt(dictionary(hybrid(2,32),heuristic(use_first(halving,approximation))))": 235,
"opt(dictionary(hybrid(2,32),heuristic(use_first(halving,delta_largest))))": 245,
"opt(dictionary(hybrid(2,64),continued_fractions(binary)))": 234,
"opt(dictionary(hybrid(2,64),continued_fractions(co_binary)))": 234,
"opt(dictionary(hybrid(2,64),continued_fractions(dichotomic)))": 232,
"opt(dictionary(hybrid(2,64),heuristic(use_first(halving,approximation))))": 234,
"opt(dictionary(hybrid(2,64),heuristic(use_first(halving,delta_largest))))": 248,
"opt(dictionary(hybrid(3,0),continued_fractions(binary)))": 330,
"opt(dictionary(hybrid(3,0),continued_fractions(co_binary)))": 330,
"opt(dictionary(hybrid(3,0),continued_fractions(dichotomic)))": 232,
"opt(dictionary(hybrid(3,0),heuristic(use_first(halving,approximation))))": 330,
"opt(dictionary(hybrid(3,0),heuristic(use_first(halving,delta_largest))))": 435,
"opt(dictionary(hybrid(3,16),continued_fractions(binary)))": 239,
"opt(dictionary(hybrid(3,16),continued_fractions(co_binary)))": 239,
"opt(dictionary(hybrid(3,16),continued_fractions(dichotomic)))": 239,
"opt(dictionary(hybrid(3,16),heuristic(use_first(halving,approximation))))": 239,
"opt(dictionary(hybrid(3,16),heuristic(use_first(halving,delta_largest))))": 239,
"opt(dictionary(hybrid(3,32),continued_fractions(binary)))": 235,
"opt(dictionary(hybrid(3,32),continued_fractions(co_binary)))": 235,
"opt(dictionary(hybrid(3,32),continued_fractions(dichotomic)))": 234,
"opt(dictionary(hybrid(3,32),heuristic(use_first(halving,approximation))))": 235,
"opt(dictionary(hybrid(3,32),heuristic(use_first(halving,delta_largest))))": 245,
"opt(dictionary(hybrid(3,64),continued_fractions(binary)))": 234,
"opt(dictionary(hybrid(3,64),continued_fractions(co_binary)))": 234,
"opt(dictionary(hybrid(3,64),continued_fractions(dichotomic)))": 232,
"opt(dictionary(hybrid(3,64),heuristic(use_first(halving,approximation))))": 234,
"opt(dictionary(hybrid(3,64),heuristic(use_first(halving,delta_largest))))": 248,
"opt(dictionary(hybrid(4,0),continued_fractions(binary)))": 330,
"opt(dictionary(hybrid(4,0),continued_fractions(co_binary)))": 330,
"opt(dictionary(hybrid(4,0),continued_fractions(dichotomic)))": 232,
"opt(dictionary(hybrid(4,0),heuristic(use_first(halving,approximation))))": 330,
"opt(dictionary(hybrid(4,0),heuristic(use_first(halving,delta_largest))))": 435,
"opt(dictionary(hybrid(4,16),continued_fractions(binary)))": 239,
"opt(dictionary(hybrid(4,16),continued_fractions(co_binary)))": 239,
"opt(dictionary(hybrid(4,16),continued_fractions(dichotomic)))": 239,
"opt(dictionary(hybrid(4,16),heuristic(use_first(halving,approximation))))": 239,
"opt(dictionary(hybrid(4,16),heuristic(use_first(halving,delta_largest))))": 239,
"opt(dictionary(hybrid(4,32),continued_fractions(binary)))": 235,
"opt(dictionary(hybrid(4,32),continued_fractions(co_binary)))": 235,
"opt(dictionary(hybrid(4,32),continued_fractions(dichotomic)))": 234,
"opt(dictionary(hybrid(4,32),heuristic(use_first(halving,approximation))))": 235,
"opt(dictionary(hybrid(4,32),heuristic(use_first(halving,delta_largest))))": 245,
"opt(dictionary(hybrid(4,64),continued_fractions(binary)))": 234,
"opt(dictionary(hybrid(4,64),continued_fractions(co_binary)))": 234,
"opt(dictionary(hybrid(4,64),continued_fractions(dichotomic)))": 232,
"opt(dictionary(hybrid(4,64),heuristic(use_first(halving,approximation))))": 234,
"opt(dictionary(hybrid(4,64),heuristic(use_first(halving,delta_largest))))": 248,
"opt(dictionary(hybrid(5,0),continued_fractions(binary)))": 330,
"opt(dictionary(hybrid(5,0),continued_fractions(co_binary)))": 330,
"opt(dictionary(hybrid(5,0),continued_fractions(dichotomic)))": 232,
"opt(dictionary(hybrid(5,0),heuristic(use_first(halving,approximation))))": 330,
"opt(dictionary(hybrid(5,0),heuristic(use_first(halving,delta_largest))))": 435,
"opt(dictionary(hybrid(5,16),continued_fractions(binary)))": 239,
"opt(dictionary(hybrid(5,16),continued_fractions(co_binary)))": 239,
"opt(dictionary(hybrid(5,16),continued_fractions(dichotomic)))": 239,
"opt(dictionary(hybrid(5,16),heuristic(use_first(halving,approximation))))": 239,
"opt(dictionary(hybrid(5,16),heuristic(use_first(halving,delta_largest))))": 239,
"opt(dictionary(hybrid(5,32),continued_fractions(binary)))": 235,
"opt(dictionary(hybrid(5,32),continued_fractions(co_binary)))": 235,
"opt(dictionary(hybrid(5,32),continued_fractions(dichotomic)))": 234,
"opt(dictionary(hybrid(5,32),heuristic(use_first(halving,approximation))))": 235,
"opt(dictionary(hybrid(5,32),heuristic(use_first(halving,delta_largest))))": 245,
"opt(dictionary(hybrid(5,64),continued_fractions(binary)))": 234,
"opt(dictionary(hybrid(5,64),continued_fractions(co_binary)))": 234,
"opt(dictionary(hybrid(5,64),continued_fractions(dichotomic)))": 232,
"opt(dictionary(hybrid(5,64),heuristic(use_first(halving,approximation))))": 234,
"opt(dictionary(hybrid(5,64),heuristic(use_first(halving,delta_largest))))": 248,
"opt(dictionary(hybrid(6,0),continued_fractions(binary)))": 330,
"opt(dictionary(hybrid(6,0),continued_fractions(co_binary)))": 330,
"opt(dictionary(hybrid(6,0),continued_fractions(dichotomic)))": 232,
"opt(dictionary(hybrid(6,0),heuristic(use_first(halving,approximation))))": 330,
"opt(dictionary(hybrid(6,0),heuristic(use_first(halving,delta_largest))))": 435,
"opt(dictionary(hybrid(6,16),continued_fractions(binary)))": 239,
"opt(dictionary(hybrid(6,16),continued_fractions(co_binary)))": 239,
"opt(dictionary(hybrid(6,16),continued_fractions(dichotomic)))": 239,
"opt(dictionary(hybrid(6,16),heuristic(use_first(halving,approximation))))": 239,
"opt(dictionary(hybrid(6,16),heuristic(use_first(halving,delta_largest))))": 239,
"opt(dictionary(hybrid(6,32),continued_fractions(binary)))": 235,
"opt(dictionary(hybrid(6,32),continued_fractions(co_binary)))": 235,
"opt(dictionary(hybrid(6,32),continued_fractions(dichotomic)))": 234,
"opt(dictionary(hybrid(6,32),heuristic(use_first(halving,approximation))))": 235,
"opt(dictionary(hybrid(6,32),heuristic(use_first(halving,delta_largest))))": 245,
"opt(dictionary(hybrid(6,64),continued_fractions(binary)))": 234,
"opt(dictionary(hybrid(6,64),continued_fractions(co_binary)))": 234,
"opt(dictionary(hybrid(6,64),continued_fractions(dichotomic)))": 232,
"opt(dictionary(hybrid(6,64),heuristic(use_first(halving,approximation))))": 234,
"opt(dictionary(hybrid(6,64),heuristic(use_first(halving,delta_largest))))": 248,
"opt(dictionary(hybrid(7,0),continued_fractions(binary)))": 330,
"opt(dictionary(hybrid(7,0),continued_fractions(co_binary)))": 330,
"opt(dictionary(hybrid(7,0),continued_fractions(dichotomic)))": 232,
"opt(dictionary(hybrid(7,0),heuristic(use_first(halving,approximation))))": 330,
"opt(dictionary(hybrid(7,0),heuristic(use_first(halving,delta_largest))))": 435,
"opt(dictionary(hybrid(7,16),continued_fractions(binary)))": 239,
"opt(dictionary(hybrid(7,16),continued_fractions(co_binary)))": 239,
"opt(dictionary(hybrid(7,16),continued_fractions(dichotomic)))": 239,
"opt(dictionary(hybrid(7,16),heuristic(use_first(halving,approximation))))": 239,
"opt(dictionary(hybrid(7,16),heuristic(use_first(halving,delta_largest))))": 239,
"opt(dictionary(hybrid(7,32),continued_fractions(binary)))": 235,
"opt(dictionary(hybrid(7,32),continued_fractions(co_binary)))": 235,
"opt(dictionary(hybrid(7,32),continued_fractions(dichotomic)))": 234,
"opt(dictionary(hybrid(7,32),heuristic(use_first(halving,approximation))))": 235,
"opt(dictionary(hybrid(7,32),heuristic(use_first(halving,delta_largest))))": 245,
"opt(dictionary(hybrid(7,64),continued_fractions(binary)))": 234,
"opt(dictionary(hybrid(7,64),continued_fractions(co_binary)))": 234,
"opt(dictionary(hybrid(7,64),continued_fractions(dichotomic)))": 232,
"opt(dictionary(hybrid(7,64),heuristic(use_first(halving,approximation))))": 234,
"opt(dictionary(hybrid(7,64),heuristic(use_first(halving,delta_largest))))": 248,
"opt(dictionary(hybrid(8,0),continued_fractions(binary)))": 330,
"opt(dictionary(hybrid(8,0),continued_fractions(co_binary)))": 330,
"opt(dictionary(hybrid(8,0),continued_fractions(dichotomic)))": 232,
"opt(dictionary(hybrid(8,0),heuristic(use_first(halving,approximation))))": 330,
"opt(dictionary(hybrid(8,0),heuristic(use_first(halving,delta_largest))))": 435,
"opt(dictionary(hybrid(8,16),continued_fractions(binary)))": 239,
"opt(dictionary(hybrid(8,16),continued_fractions(co_binary)))": 239,
"opt(dictionary(hybrid(8,16),continued_fractions(dichotomic)))": 239,
"opt(dictionary(hybrid(8,16),heuristic(use_first(halving,approximation))))": 239,
"opt(dictionary(hybrid(8,16),heuristic(use_first(halving,delta_largest))))": 239,
"opt(dictionary(hybrid(8,32),continued_fractions(binary)))": 235,
"opt(dictionary(hybrid(8,32),continued_fractions(co_binary)))": 235,
"opt(dictionary(hybrid(8,32),continued_fractions(dichotomic)))": 234,
"opt(dictionary(hybrid(8,32),heuristic(use_first(halving,approximation))))": 235,
"opt(dictionary(hybrid(8,32),heuristic(use_first(halving,delta_largest))))": 245,
"opt(dictionary(hybrid(8,64),continued_fractions(binary)))": 234,
"opt(dictionary(hybrid(8,64),continued_fractions(co_binary)))": 234,
"opt(dictionary(hybrid(8,64),continued_fractions(dichotomic)))": 232,
"opt(dictionary(hybrid(8,64),heuristic(use_first(halving,approximation))))": 234,
"opt(dictionary(hybrid(8,64),heuristic(use_first(halving,delta_largest))))": 248,
"opt(dictionary(run_length(0),continued_fractions(binary)))": 330,
"opt(dictionary(run_length(0),continued_fractions(co_binary)))": 330,
"opt(dictionary(run_length(0),continued_fractions(dichotomic)))": 232,
"opt(dictionary(run_length(0),heuristic(use_first(halving,approximation))))": 330,
"opt(dictionary(run_length(0),heuristic(use_first(halving,delta_largest))))": 435,
"opt(dictionary(run_length(128),continued_fractions(binary)))": 232,
"opt(dictionary(run_length(128),continued_fractions(co_binary)))": 232,
"opt(dictionary(run_length(128),continued_fractions(dichotomic)))": 232,
"opt(dictionary(run_length(128),heuristic(use_first(halving,approximation))))": 232,
"opt(dictionary(run_length(128),heuristic(use_first(halving,delta_largest))))": 258,
"opt(dictionary(run_length(16),continued_fractions(binary)))": 239,
"opt(dictionary(run_length(16),continued_fractions(co_binary)))": 239,
"opt(dictionary(run_length(16),continued_fractions(dichotomic)))": 239,
"opt(dictionary(run_length(16),heuristic(use_first(halving,approximation))))": 239,
"opt(dictionary(run_length(16),heuristic(use_first(halving,delta_largest))))": 239,
"opt(dictionary(run_length(32),continued_fractions(binary)))": 235,
"opt(dictionary(run_length(32),continued_fractions(co_binary)))": 235,
"opt(dictionary(run_length(32),continued_fractions(dichotomic)))": 234,
"opt(dictionary(run_length(32),heuristic(use_first(halving,approximation))))": 235,
"opt(dictionary(run_length(32),heuristic(use_first(halving,delta_largest))))": 245,
"opt(dictionary(run_length(64),continued_fractions(binary)))": 234,
"opt(dictionary(run_length(64),continued_fractions(co_binary)))": 234,
"opt(dictionary(run_length(64),continued_fractions(dichotomic)))": 232,
"opt(dictionary(run_length(64),heuristic(use_first(halving,approximation))))": 234,
"opt(dictionary(run_length(64),heuristic(use_first(halving,delta_largest))))": 248,
"opt(dictionary(sliding_window(128),continued_fractions(binary)))": 270,
"opt(dictionary(sliding_window(128),continued_fractions(co_binary)))": 270,
"opt(dictionary(sliding_window(128),continued_fractions(dichotomic)))": 256,
"opt(dictionary(sliding_window(128),heuristic(use_first(halving,approximation))))": 236,
"opt(dictionary(sliding_window(128),heuristic(use_first(halving,delta_largest))))": 261,
"opt(dictionary(sliding_window(16),continued_fractions(binary)))": 240,
"opt(dictionary(sliding_window(16),continued_fractions(co_binary)))": 240,
"opt(dictionary(sliding_window(16),continued_fractions(dichotomic)))": 240,
"opt(dictionary(sliding_window(16),heuristic(use_first(halving,approximation))))": 241,
"opt(dictionary(sliding_window(16),heuristic(use_first(halving,delta_largest))))": 245,
"opt(dictionary(sliding_window(32),continued_fractions(binary)))": 237,
"opt(dictionary(sliding_window(32),continued_fractions(co_binary)))": 237,
"opt(dictionary(sliding_window(32),continued_fractions(dichotomic)))": 234,
"opt(dictionary(sliding_window(32),heuristic(use_first(halving,approximation))))": 240,
"opt(dictionary(sliding_window(32),heuristic(use_first(halving,delta_largest))))": 253,
"opt(dictionary(sliding_window(4),continued_fractions(binary)))": 278,
"opt(dictionary(sliding_window(4),continued_fractions(co_binary)))": 278,
"opt(dictionary(sliding_window(4),continued_fractions(dichotomic)))": 278,
"opt(dictionary(sliding_window(4),heuristic(use_first(halving,approximation))))": 278,
"opt(dictionary(sliding_window(4),heuristic(use_first(halving,delta_largest))))": 278,
"opt(dictionary(sliding_window(64),continued_fractions(binary)))": 242,
"opt(dictionary(sliding_window(64),continued_fractions(co_binary)))": 242,
"opt(dictionary(sliding_window(64),continued_fractions(dichotomic)))": 243,
"opt(dictionary(sliding_window(64),heuristic(use_first(halving,approximation))))": 235,
"opt(dictionary(sliding_window(64),heuristic(use_first(halving,delta_largest))))": 256,
"opt(dictionary(sliding_window(8),continued_fractions(binary)))": 251,
"opt(dictionary(sliding_window(8),continued_fractions(co_binary)))": 251,
"opt(dictionary(sliding_window(8),continued_fractions(dichotomic)))": 251,
"opt(dictionary(sliding_window(8),heuristic(use_first(halving,approximation))))": 252,
"opt(dictionary(sliding_window(8),heuristic(use_first(halving,delta_largest))))": 252,
"opt(runs(continued_fractions(binary)))": 232,
"opt(runs(continued_fractions(co_binary)))": 232,
"opt(runs(continued_fractions(dichotomic)))": 231,
"opt(runs(heuristic(use_first(halving,approximation))))": 231,
"opt(runs(heuristic(use_first(halving,delta_largest))))": 234
} addchain-0.4.0/alg/ensemble/testdata/p222117_field.golden 0000664 0000000 0000000 00000035321 15143052566 0022702 0 ustar 00root root 0000000 0000000 {
"opt(dictionary(hybrid(2,0),continued_fractions(binary)))": 437,
"opt(dictionary(hybrid(2,0),continued_fractions(co_binary)))": 437,
"opt(dictionary(hybrid(2,0),continued_fractions(dichotomic)))": 235,
"opt(dictionary(hybrid(2,0),heuristic(use_first(halving,approximation))))": 331,
"opt(dictionary(hybrid(2,0),heuristic(use_first(halving,delta_largest))))": 435,
"opt(dictionary(hybrid(2,16),continued_fractions(binary)))": 242,
"opt(dictionary(hybrid(2,16),continued_fractions(co_binary)))": 242,
"opt(dictionary(hybrid(2,16),continued_fractions(dichotomic)))": 242,
"opt(dictionary(hybrid(2,16),heuristic(use_first(halving,approximation))))": 242,
"opt(dictionary(hybrid(2,16),heuristic(use_first(halving,delta_largest))))": 244,
"opt(dictionary(hybrid(2,32),continued_fractions(binary)))": 237,
"opt(dictionary(hybrid(2,32),continued_fractions(co_binary)))": 237,
"opt(dictionary(hybrid(2,32),continued_fractions(dichotomic)))": 236,
"opt(dictionary(hybrid(2,32),heuristic(use_first(halving,approximation))))": 236,
"opt(dictionary(hybrid(2,32),heuristic(use_first(halving,delta_largest))))": 241,
"opt(dictionary(hybrid(2,64),continued_fractions(binary)))": 235,
"opt(dictionary(hybrid(2,64),continued_fractions(co_binary)))": 235,
"opt(dictionary(hybrid(2,64),continued_fractions(dichotomic)))": 235,
"opt(dictionary(hybrid(2,64),heuristic(use_first(halving,approximation))))": 235,
"opt(dictionary(hybrid(2,64),heuristic(use_first(halving,delta_largest))))": 256,
"opt(dictionary(hybrid(3,0),continued_fractions(binary)))": 437,
"opt(dictionary(hybrid(3,0),continued_fractions(co_binary)))": 437,
"opt(dictionary(hybrid(3,0),continued_fractions(dichotomic)))": 235,
"opt(dictionary(hybrid(3,0),heuristic(use_first(halving,approximation))))": 331,
"opt(dictionary(hybrid(3,0),heuristic(use_first(halving,delta_largest))))": 435,
"opt(dictionary(hybrid(3,16),continued_fractions(binary)))": 242,
"opt(dictionary(hybrid(3,16),continued_fractions(co_binary)))": 242,
"opt(dictionary(hybrid(3,16),continued_fractions(dichotomic)))": 242,
"opt(dictionary(hybrid(3,16),heuristic(use_first(halving,approximation))))": 242,
"opt(dictionary(hybrid(3,16),heuristic(use_first(halving,delta_largest))))": 244,
"opt(dictionary(hybrid(3,32),continued_fractions(binary)))": 237,
"opt(dictionary(hybrid(3,32),continued_fractions(co_binary)))": 237,
"opt(dictionary(hybrid(3,32),continued_fractions(dichotomic)))": 236,
"opt(dictionary(hybrid(3,32),heuristic(use_first(halving,approximation))))": 236,
"opt(dictionary(hybrid(3,32),heuristic(use_first(halving,delta_largest))))": 241,
"opt(dictionary(hybrid(3,64),continued_fractions(binary)))": 235,
"opt(dictionary(hybrid(3,64),continued_fractions(co_binary)))": 235,
"opt(dictionary(hybrid(3,64),continued_fractions(dichotomic)))": 235,
"opt(dictionary(hybrid(3,64),heuristic(use_first(halving,approximation))))": 235,
"opt(dictionary(hybrid(3,64),heuristic(use_first(halving,delta_largest))))": 256,
"opt(dictionary(hybrid(4,0),continued_fractions(binary)))": 330,
"opt(dictionary(hybrid(4,0),continued_fractions(co_binary)))": 330,
"opt(dictionary(hybrid(4,0),continued_fractions(dichotomic)))": 242,
"opt(dictionary(hybrid(4,0),heuristic(use_first(halving,approximation))))": 278,
"opt(dictionary(hybrid(4,0),heuristic(use_first(halving,delta_largest))))": 434,
"opt(dictionary(hybrid(4,16),continued_fractions(binary)))": 241,
"opt(dictionary(hybrid(4,16),continued_fractions(co_binary)))": 241,
"opt(dictionary(hybrid(4,16),continued_fractions(dichotomic)))": 241,
"opt(dictionary(hybrid(4,16),heuristic(use_first(halving,approximation))))": 241,
"opt(dictionary(hybrid(4,16),heuristic(use_first(halving,delta_largest))))": 243,
"opt(dictionary(hybrid(4,32),continued_fractions(binary)))": 235,
"opt(dictionary(hybrid(4,32),continued_fractions(co_binary)))": 235,
"opt(dictionary(hybrid(4,32),continued_fractions(dichotomic)))": 235,
"opt(dictionary(hybrid(4,32),heuristic(use_first(halving,approximation))))": 235,
"opt(dictionary(hybrid(4,32),heuristic(use_first(halving,delta_largest))))": 240,
"opt(dictionary(hybrid(4,64),continued_fractions(binary)))": 235,
"opt(dictionary(hybrid(4,64),continued_fractions(co_binary)))": 235,
"opt(dictionary(hybrid(4,64),continued_fractions(dichotomic)))": 235,
"opt(dictionary(hybrid(4,64),heuristic(use_first(halving,approximation))))": 235,
"opt(dictionary(hybrid(4,64),heuristic(use_first(halving,delta_largest))))": 256,
"opt(dictionary(hybrid(5,0),continued_fractions(binary)))": 330,
"opt(dictionary(hybrid(5,0),continued_fractions(co_binary)))": 330,
"opt(dictionary(hybrid(5,0),continued_fractions(dichotomic)))": 242,
"opt(dictionary(hybrid(5,0),heuristic(use_first(halving,approximation))))": 278,
"opt(dictionary(hybrid(5,0),heuristic(use_first(halving,delta_largest))))": 434,
"opt(dictionary(hybrid(5,16),continued_fractions(binary)))": 241,
"opt(dictionary(hybrid(5,16),continued_fractions(co_binary)))": 241,
"opt(dictionary(hybrid(5,16),continued_fractions(dichotomic)))": 241,
"opt(dictionary(hybrid(5,16),heuristic(use_first(halving,approximation))))": 241,
"opt(dictionary(hybrid(5,16),heuristic(use_first(halving,delta_largest))))": 243,
"opt(dictionary(hybrid(5,32),continued_fractions(binary)))": 235,
"opt(dictionary(hybrid(5,32),continued_fractions(co_binary)))": 235,
"opt(dictionary(hybrid(5,32),continued_fractions(dichotomic)))": 235,
"opt(dictionary(hybrid(5,32),heuristic(use_first(halving,approximation))))": 235,
"opt(dictionary(hybrid(5,32),heuristic(use_first(halving,delta_largest))))": 240,
"opt(dictionary(hybrid(5,64),continued_fractions(binary)))": 235,
"opt(dictionary(hybrid(5,64),continued_fractions(co_binary)))": 235,
"opt(dictionary(hybrid(5,64),continued_fractions(dichotomic)))": 235,
"opt(dictionary(hybrid(5,64),heuristic(use_first(halving,approximation))))": 235,
"opt(dictionary(hybrid(5,64),heuristic(use_first(halving,delta_largest))))": 256,
"opt(dictionary(hybrid(6,0),continued_fractions(binary)))": 330,
"opt(dictionary(hybrid(6,0),continued_fractions(co_binary)))": 330,
"opt(dictionary(hybrid(6,0),continued_fractions(dichotomic)))": 242,
"opt(dictionary(hybrid(6,0),heuristic(use_first(halving,approximation))))": 278,
"opt(dictionary(hybrid(6,0),heuristic(use_first(halving,delta_largest))))": 434,
"opt(dictionary(hybrid(6,16),continued_fractions(binary)))": 241,
"opt(dictionary(hybrid(6,16),continued_fractions(co_binary)))": 241,
"opt(dictionary(hybrid(6,16),continued_fractions(dichotomic)))": 241,
"opt(dictionary(hybrid(6,16),heuristic(use_first(halving,approximation))))": 241,
"opt(dictionary(hybrid(6,16),heuristic(use_first(halving,delta_largest))))": 243,
"opt(dictionary(hybrid(6,32),continued_fractions(binary)))": 235,
"opt(dictionary(hybrid(6,32),continued_fractions(co_binary)))": 235,
"opt(dictionary(hybrid(6,32),continued_fractions(dichotomic)))": 235,
"opt(dictionary(hybrid(6,32),heuristic(use_first(halving,approximation))))": 235,
"opt(dictionary(hybrid(6,32),heuristic(use_first(halving,delta_largest))))": 240,
"opt(dictionary(hybrid(6,64),continued_fractions(binary)))": 235,
"opt(dictionary(hybrid(6,64),continued_fractions(co_binary)))": 235,
"opt(dictionary(hybrid(6,64),continued_fractions(dichotomic)))": 235,
"opt(dictionary(hybrid(6,64),heuristic(use_first(halving,approximation))))": 235,
"opt(dictionary(hybrid(6,64),heuristic(use_first(halving,delta_largest))))": 256,
"opt(dictionary(hybrid(7,0),continued_fractions(binary)))": 330,
"opt(dictionary(hybrid(7,0),continued_fractions(co_binary)))": 330,
"opt(dictionary(hybrid(7,0),continued_fractions(dichotomic)))": 242,
"opt(dictionary(hybrid(7,0),heuristic(use_first(halving,approximation))))": 278,
"opt(dictionary(hybrid(7,0),heuristic(use_first(halving,delta_largest))))": 434,
"opt(dictionary(hybrid(7,16),continued_fractions(binary)))": 241,
"opt(dictionary(hybrid(7,16),continued_fractions(co_binary)))": 241,
"opt(dictionary(hybrid(7,16),continued_fractions(dichotomic)))": 241,
"opt(dictionary(hybrid(7,16),heuristic(use_first(halving,approximation))))": 241,
"opt(dictionary(hybrid(7,16),heuristic(use_first(halving,delta_largest))))": 243,
"opt(dictionary(hybrid(7,32),continued_fractions(binary)))": 235,
"opt(dictionary(hybrid(7,32),continued_fractions(co_binary)))": 235,
"opt(dictionary(hybrid(7,32),continued_fractions(dichotomic)))": 235,
"opt(dictionary(hybrid(7,32),heuristic(use_first(halving,approximation))))": 235,
"opt(dictionary(hybrid(7,32),heuristic(use_first(halving,delta_largest))))": 240,
"opt(dictionary(hybrid(7,64),continued_fractions(binary)))": 235,
"opt(dictionary(hybrid(7,64),continued_fractions(co_binary)))": 235,
"opt(dictionary(hybrid(7,64),continued_fractions(dichotomic)))": 235,
"opt(dictionary(hybrid(7,64),heuristic(use_first(halving,approximation))))": 235,
"opt(dictionary(hybrid(7,64),heuristic(use_first(halving,delta_largest))))": 256,
"opt(dictionary(hybrid(8,0),continued_fractions(binary)))": 330,
"opt(dictionary(hybrid(8,0),continued_fractions(co_binary)))": 330,
"opt(dictionary(hybrid(8,0),continued_fractions(dichotomic)))": 242,
"opt(dictionary(hybrid(8,0),heuristic(use_first(halving,approximation))))": 278,
"opt(dictionary(hybrid(8,0),heuristic(use_first(halving,delta_largest))))": 434,
"opt(dictionary(hybrid(8,16),continued_fractions(binary)))": 241,
"opt(dictionary(hybrid(8,16),continued_fractions(co_binary)))": 241,
"opt(dictionary(hybrid(8,16),continued_fractions(dichotomic)))": 241,
"opt(dictionary(hybrid(8,16),heuristic(use_first(halving,approximation))))": 241,
"opt(dictionary(hybrid(8,16),heuristic(use_first(halving,delta_largest))))": 243,
"opt(dictionary(hybrid(8,32),continued_fractions(binary)))": 235,
"opt(dictionary(hybrid(8,32),continued_fractions(co_binary)))": 235,
"opt(dictionary(hybrid(8,32),continued_fractions(dichotomic)))": 235,
"opt(dictionary(hybrid(8,32),heuristic(use_first(halving,approximation))))": 235,
"opt(dictionary(hybrid(8,32),heuristic(use_first(halving,delta_largest))))": 240,
"opt(dictionary(hybrid(8,64),continued_fractions(binary)))": 235,
"opt(dictionary(hybrid(8,64),continued_fractions(co_binary)))": 235,
"opt(dictionary(hybrid(8,64),continued_fractions(dichotomic)))": 235,
"opt(dictionary(hybrid(8,64),heuristic(use_first(halving,approximation))))": 235,
"opt(dictionary(hybrid(8,64),heuristic(use_first(halving,delta_largest))))": 256,
"opt(dictionary(run_length(0),continued_fractions(binary)))": 437,
"opt(dictionary(run_length(0),continued_fractions(co_binary)))": 437,
"opt(dictionary(run_length(0),continued_fractions(dichotomic)))": 235,
"opt(dictionary(run_length(0),heuristic(use_first(halving,approximation))))": 331,
"opt(dictionary(run_length(0),heuristic(use_first(halving,delta_largest))))": 435,
"opt(dictionary(run_length(128),continued_fractions(binary)))": 239,
"opt(dictionary(run_length(128),continued_fractions(co_binary)))": 239,
"opt(dictionary(run_length(128),continued_fractions(dichotomic)))": 234,
"opt(dictionary(run_length(128),heuristic(use_first(halving,approximation))))": 238,
"opt(dictionary(run_length(128),heuristic(use_first(halving,delta_largest))))": 267,
"opt(dictionary(run_length(16),continued_fractions(binary)))": 242,
"opt(dictionary(run_length(16),continued_fractions(co_binary)))": 242,
"opt(dictionary(run_length(16),continued_fractions(dichotomic)))": 242,
"opt(dictionary(run_length(16),heuristic(use_first(halving,approximation))))": 242,
"opt(dictionary(run_length(16),heuristic(use_first(halving,delta_largest))))": 244,
"opt(dictionary(run_length(32),continued_fractions(binary)))": 237,
"opt(dictionary(run_length(32),continued_fractions(co_binary)))": 237,
"opt(dictionary(run_length(32),continued_fractions(dichotomic)))": 236,
"opt(dictionary(run_length(32),heuristic(use_first(halving,approximation))))": 236,
"opt(dictionary(run_length(32),heuristic(use_first(halving,delta_largest))))": 241,
"opt(dictionary(run_length(64),continued_fractions(binary)))": 235,
"opt(dictionary(run_length(64),continued_fractions(co_binary)))": 235,
"opt(dictionary(run_length(64),continued_fractions(dichotomic)))": 235,
"opt(dictionary(run_length(64),heuristic(use_first(halving,approximation))))": 235,
"opt(dictionary(run_length(64),heuristic(use_first(halving,delta_largest))))": 256,
"opt(dictionary(sliding_window(128),continued_fractions(binary)))": 270,
"opt(dictionary(sliding_window(128),continued_fractions(co_binary)))": 270,
"opt(dictionary(sliding_window(128),continued_fractions(dichotomic)))": 263,
"opt(dictionary(sliding_window(128),heuristic(use_first(halving,approximation))))": 239,
"opt(dictionary(sliding_window(128),heuristic(use_first(halving,delta_largest))))": 267,
"opt(dictionary(sliding_window(16),continued_fractions(binary)))": 242,
"opt(dictionary(sliding_window(16),continued_fractions(co_binary)))": 242,
"opt(dictionary(sliding_window(16),continued_fractions(dichotomic)))": 242,
"opt(dictionary(sliding_window(16),heuristic(use_first(halving,approximation))))": 242,
"opt(dictionary(sliding_window(16),heuristic(use_first(halving,delta_largest))))": 242,
"opt(dictionary(sliding_window(32),continued_fractions(binary)))": 245,
"opt(dictionary(sliding_window(32),continued_fractions(co_binary)))": 245,
"opt(dictionary(sliding_window(32),continued_fractions(dichotomic)))": 242,
"opt(dictionary(sliding_window(32),heuristic(use_first(halving,approximation))))": 239,
"opt(dictionary(sliding_window(32),heuristic(use_first(halving,delta_largest))))": 252,
"opt(dictionary(sliding_window(4),continued_fractions(binary)))": 278,
"opt(dictionary(sliding_window(4),continued_fractions(co_binary)))": 278,
"opt(dictionary(sliding_window(4),continued_fractions(dichotomic)))": 278,
"opt(dictionary(sliding_window(4),heuristic(use_first(halving,approximation))))": 278,
"opt(dictionary(sliding_window(4),heuristic(use_first(halving,delta_largest))))": 278,
"opt(dictionary(sliding_window(64),continued_fractions(binary)))": 244,
"opt(dictionary(sliding_window(64),continued_fractions(co_binary)))": 244,
"opt(dictionary(sliding_window(64),continued_fractions(dichotomic)))": 244,
"opt(dictionary(sliding_window(64),heuristic(use_first(halving,approximation))))": 238,
"opt(dictionary(sliding_window(64),heuristic(use_first(halving,delta_largest))))": 254,
"opt(dictionary(sliding_window(8),continued_fractions(binary)))": 253,
"opt(dictionary(sliding_window(8),continued_fractions(co_binary)))": 253,
"opt(dictionary(sliding_window(8),continued_fractions(dichotomic)))": 253,
"opt(dictionary(sliding_window(8),heuristic(use_first(halving,approximation))))": 253,
"opt(dictionary(sliding_window(8),heuristic(use_first(halving,delta_largest))))": 253,
"opt(runs(continued_fractions(binary)))": 235,
"opt(runs(continued_fractions(co_binary)))": 235,
"opt(runs(continued_fractions(dichotomic)))": 233,
"opt(runs(heuristic(use_first(halving,approximation))))": 235,
"opt(runs(heuristic(use_first(halving,delta_largest))))": 235
} addchain-0.4.0/alg/ensemble/testdata/p224_field.golden 0000664 0000000 0000000 00000035321 15143052566 0022453 0 ustar 00root root 0000000 0000000 {
"opt(dictionary(hybrid(2,0),continued_fractions(binary)))": 240,
"opt(dictionary(hybrid(2,0),continued_fractions(co_binary)))": 240,
"opt(dictionary(hybrid(2,0),continued_fractions(dichotomic)))": 235,
"opt(dictionary(hybrid(2,0),heuristic(use_first(halving,approximation))))": 240,
"opt(dictionary(hybrid(2,0),heuristic(use_first(halving,delta_largest))))": 288,
"opt(dictionary(hybrid(2,16),continued_fractions(binary)))": 251,
"opt(dictionary(hybrid(2,16),continued_fractions(co_binary)))": 251,
"opt(dictionary(hybrid(2,16),continued_fractions(dichotomic)))": 243,
"opt(dictionary(hybrid(2,16),heuristic(use_first(halving,approximation))))": 245,
"opt(dictionary(hybrid(2,16),heuristic(use_first(halving,delta_largest))))": 249,
"opt(dictionary(hybrid(2,32),continued_fractions(binary)))": 260,
"opt(dictionary(hybrid(2,32),continued_fractions(co_binary)))": 260,
"opt(dictionary(hybrid(2,32),continued_fractions(dichotomic)))": 238,
"opt(dictionary(hybrid(2,32),heuristic(use_first(halving,approximation))))": 246,
"opt(dictionary(hybrid(2,32),heuristic(use_first(halving,delta_largest))))": 258,
"opt(dictionary(hybrid(2,64),continued_fractions(binary)))": 259,
"opt(dictionary(hybrid(2,64),continued_fractions(co_binary)))": 259,
"opt(dictionary(hybrid(2,64),continued_fractions(dichotomic)))": 237,
"opt(dictionary(hybrid(2,64),heuristic(use_first(halving,approximation))))": 245,
"opt(dictionary(hybrid(2,64),heuristic(use_first(halving,delta_largest))))": 257,
"opt(dictionary(hybrid(3,0),continued_fractions(binary)))": 240,
"opt(dictionary(hybrid(3,0),continued_fractions(co_binary)))": 240,
"opt(dictionary(hybrid(3,0),continued_fractions(dichotomic)))": 235,
"opt(dictionary(hybrid(3,0),heuristic(use_first(halving,approximation))))": 240,
"opt(dictionary(hybrid(3,0),heuristic(use_first(halving,delta_largest))))": 288,
"opt(dictionary(hybrid(3,16),continued_fractions(binary)))": 251,
"opt(dictionary(hybrid(3,16),continued_fractions(co_binary)))": 251,
"opt(dictionary(hybrid(3,16),continued_fractions(dichotomic)))": 243,
"opt(dictionary(hybrid(3,16),heuristic(use_first(halving,approximation))))": 245,
"opt(dictionary(hybrid(3,16),heuristic(use_first(halving,delta_largest))))": 249,
"opt(dictionary(hybrid(3,32),continued_fractions(binary)))": 260,
"opt(dictionary(hybrid(3,32),continued_fractions(co_binary)))": 260,
"opt(dictionary(hybrid(3,32),continued_fractions(dichotomic)))": 238,
"opt(dictionary(hybrid(3,32),heuristic(use_first(halving,approximation))))": 246,
"opt(dictionary(hybrid(3,32),heuristic(use_first(halving,delta_largest))))": 258,
"opt(dictionary(hybrid(3,64),continued_fractions(binary)))": 259,
"opt(dictionary(hybrid(3,64),continued_fractions(co_binary)))": 259,
"opt(dictionary(hybrid(3,64),continued_fractions(dichotomic)))": 237,
"opt(dictionary(hybrid(3,64),heuristic(use_first(halving,approximation))))": 245,
"opt(dictionary(hybrid(3,64),heuristic(use_first(halving,delta_largest))))": 257,
"opt(dictionary(hybrid(4,0),continued_fractions(binary)))": 240,
"opt(dictionary(hybrid(4,0),continued_fractions(co_binary)))": 240,
"opt(dictionary(hybrid(4,0),continued_fractions(dichotomic)))": 235,
"opt(dictionary(hybrid(4,0),heuristic(use_first(halving,approximation))))": 240,
"opt(dictionary(hybrid(4,0),heuristic(use_first(halving,delta_largest))))": 288,
"opt(dictionary(hybrid(4,16),continued_fractions(binary)))": 251,
"opt(dictionary(hybrid(4,16),continued_fractions(co_binary)))": 251,
"opt(dictionary(hybrid(4,16),continued_fractions(dichotomic)))": 243,
"opt(dictionary(hybrid(4,16),heuristic(use_first(halving,approximation))))": 245,
"opt(dictionary(hybrid(4,16),heuristic(use_first(halving,delta_largest))))": 249,
"opt(dictionary(hybrid(4,32),continued_fractions(binary)))": 260,
"opt(dictionary(hybrid(4,32),continued_fractions(co_binary)))": 260,
"opt(dictionary(hybrid(4,32),continued_fractions(dichotomic)))": 238,
"opt(dictionary(hybrid(4,32),heuristic(use_first(halving,approximation))))": 246,
"opt(dictionary(hybrid(4,32),heuristic(use_first(halving,delta_largest))))": 258,
"opt(dictionary(hybrid(4,64),continued_fractions(binary)))": 259,
"opt(dictionary(hybrid(4,64),continued_fractions(co_binary)))": 259,
"opt(dictionary(hybrid(4,64),continued_fractions(dichotomic)))": 237,
"opt(dictionary(hybrid(4,64),heuristic(use_first(halving,approximation))))": 245,
"opt(dictionary(hybrid(4,64),heuristic(use_first(halving,delta_largest))))": 257,
"opt(dictionary(hybrid(5,0),continued_fractions(binary)))": 240,
"opt(dictionary(hybrid(5,0),continued_fractions(co_binary)))": 240,
"opt(dictionary(hybrid(5,0),continued_fractions(dichotomic)))": 235,
"opt(dictionary(hybrid(5,0),heuristic(use_first(halving,approximation))))": 240,
"opt(dictionary(hybrid(5,0),heuristic(use_first(halving,delta_largest))))": 288,
"opt(dictionary(hybrid(5,16),continued_fractions(binary)))": 251,
"opt(dictionary(hybrid(5,16),continued_fractions(co_binary)))": 251,
"opt(dictionary(hybrid(5,16),continued_fractions(dichotomic)))": 243,
"opt(dictionary(hybrid(5,16),heuristic(use_first(halving,approximation))))": 245,
"opt(dictionary(hybrid(5,16),heuristic(use_first(halving,delta_largest))))": 249,
"opt(dictionary(hybrid(5,32),continued_fractions(binary)))": 260,
"opt(dictionary(hybrid(5,32),continued_fractions(co_binary)))": 260,
"opt(dictionary(hybrid(5,32),continued_fractions(dichotomic)))": 238,
"opt(dictionary(hybrid(5,32),heuristic(use_first(halving,approximation))))": 246,
"opt(dictionary(hybrid(5,32),heuristic(use_first(halving,delta_largest))))": 258,
"opt(dictionary(hybrid(5,64),continued_fractions(binary)))": 259,
"opt(dictionary(hybrid(5,64),continued_fractions(co_binary)))": 259,
"opt(dictionary(hybrid(5,64),continued_fractions(dichotomic)))": 237,
"opt(dictionary(hybrid(5,64),heuristic(use_first(halving,approximation))))": 245,
"opt(dictionary(hybrid(5,64),heuristic(use_first(halving,delta_largest))))": 257,
"opt(dictionary(hybrid(6,0),continued_fractions(binary)))": 240,
"opt(dictionary(hybrid(6,0),continued_fractions(co_binary)))": 240,
"opt(dictionary(hybrid(6,0),continued_fractions(dichotomic)))": 235,
"opt(dictionary(hybrid(6,0),heuristic(use_first(halving,approximation))))": 240,
"opt(dictionary(hybrid(6,0),heuristic(use_first(halving,delta_largest))))": 288,
"opt(dictionary(hybrid(6,16),continued_fractions(binary)))": 251,
"opt(dictionary(hybrid(6,16),continued_fractions(co_binary)))": 251,
"opt(dictionary(hybrid(6,16),continued_fractions(dichotomic)))": 243,
"opt(dictionary(hybrid(6,16),heuristic(use_first(halving,approximation))))": 245,
"opt(dictionary(hybrid(6,16),heuristic(use_first(halving,delta_largest))))": 249,
"opt(dictionary(hybrid(6,32),continued_fractions(binary)))": 260,
"opt(dictionary(hybrid(6,32),continued_fractions(co_binary)))": 260,
"opt(dictionary(hybrid(6,32),continued_fractions(dichotomic)))": 238,
"opt(dictionary(hybrid(6,32),heuristic(use_first(halving,approximation))))": 246,
"opt(dictionary(hybrid(6,32),heuristic(use_first(halving,delta_largest))))": 258,
"opt(dictionary(hybrid(6,64),continued_fractions(binary)))": 259,
"opt(dictionary(hybrid(6,64),continued_fractions(co_binary)))": 259,
"opt(dictionary(hybrid(6,64),continued_fractions(dichotomic)))": 237,
"opt(dictionary(hybrid(6,64),heuristic(use_first(halving,approximation))))": 245,
"opt(dictionary(hybrid(6,64),heuristic(use_first(halving,delta_largest))))": 257,
"opt(dictionary(hybrid(7,0),continued_fractions(binary)))": 240,
"opt(dictionary(hybrid(7,0),continued_fractions(co_binary)))": 240,
"opt(dictionary(hybrid(7,0),continued_fractions(dichotomic)))": 235,
"opt(dictionary(hybrid(7,0),heuristic(use_first(halving,approximation))))": 240,
"opt(dictionary(hybrid(7,0),heuristic(use_first(halving,delta_largest))))": 288,
"opt(dictionary(hybrid(7,16),continued_fractions(binary)))": 251,
"opt(dictionary(hybrid(7,16),continued_fractions(co_binary)))": 251,
"opt(dictionary(hybrid(7,16),continued_fractions(dichotomic)))": 243,
"opt(dictionary(hybrid(7,16),heuristic(use_first(halving,approximation))))": 245,
"opt(dictionary(hybrid(7,16),heuristic(use_first(halving,delta_largest))))": 249,
"opt(dictionary(hybrid(7,32),continued_fractions(binary)))": 260,
"opt(dictionary(hybrid(7,32),continued_fractions(co_binary)))": 260,
"opt(dictionary(hybrid(7,32),continued_fractions(dichotomic)))": 238,
"opt(dictionary(hybrid(7,32),heuristic(use_first(halving,approximation))))": 246,
"opt(dictionary(hybrid(7,32),heuristic(use_first(halving,delta_largest))))": 258,
"opt(dictionary(hybrid(7,64),continued_fractions(binary)))": 259,
"opt(dictionary(hybrid(7,64),continued_fractions(co_binary)))": 259,
"opt(dictionary(hybrid(7,64),continued_fractions(dichotomic)))": 237,
"opt(dictionary(hybrid(7,64),heuristic(use_first(halving,approximation))))": 245,
"opt(dictionary(hybrid(7,64),heuristic(use_first(halving,delta_largest))))": 257,
"opt(dictionary(hybrid(8,0),continued_fractions(binary)))": 240,
"opt(dictionary(hybrid(8,0),continued_fractions(co_binary)))": 240,
"opt(dictionary(hybrid(8,0),continued_fractions(dichotomic)))": 235,
"opt(dictionary(hybrid(8,0),heuristic(use_first(halving,approximation))))": 240,
"opt(dictionary(hybrid(8,0),heuristic(use_first(halving,delta_largest))))": 288,
"opt(dictionary(hybrid(8,16),continued_fractions(binary)))": 251,
"opt(dictionary(hybrid(8,16),continued_fractions(co_binary)))": 251,
"opt(dictionary(hybrid(8,16),continued_fractions(dichotomic)))": 243,
"opt(dictionary(hybrid(8,16),heuristic(use_first(halving,approximation))))": 245,
"opt(dictionary(hybrid(8,16),heuristic(use_first(halving,delta_largest))))": 249,
"opt(dictionary(hybrid(8,32),continued_fractions(binary)))": 260,
"opt(dictionary(hybrid(8,32),continued_fractions(co_binary)))": 260,
"opt(dictionary(hybrid(8,32),continued_fractions(dichotomic)))": 238,
"opt(dictionary(hybrid(8,32),heuristic(use_first(halving,approximation))))": 246,
"opt(dictionary(hybrid(8,32),heuristic(use_first(halving,delta_largest))))": 258,
"opt(dictionary(hybrid(8,64),continued_fractions(binary)))": 259,
"opt(dictionary(hybrid(8,64),continued_fractions(co_binary)))": 259,
"opt(dictionary(hybrid(8,64),continued_fractions(dichotomic)))": 237,
"opt(dictionary(hybrid(8,64),heuristic(use_first(halving,approximation))))": 245,
"opt(dictionary(hybrid(8,64),heuristic(use_first(halving,delta_largest))))": 257,
"opt(dictionary(run_length(0),continued_fractions(binary)))": 240,
"opt(dictionary(run_length(0),continued_fractions(co_binary)))": 240,
"opt(dictionary(run_length(0),continued_fractions(dichotomic)))": 235,
"opt(dictionary(run_length(0),heuristic(use_first(halving,approximation))))": 240,
"opt(dictionary(run_length(0),heuristic(use_first(halving,delta_largest))))": 288,
"opt(dictionary(run_length(128),continued_fractions(binary)))": 240,
"opt(dictionary(run_length(128),continued_fractions(co_binary)))": 240,
"opt(dictionary(run_length(128),continued_fractions(dichotomic)))": 235,
"opt(dictionary(run_length(128),heuristic(use_first(halving,approximation))))": 240,
"opt(dictionary(run_length(128),heuristic(use_first(halving,delta_largest))))": 288,
"opt(dictionary(run_length(16),continued_fractions(binary)))": 251,
"opt(dictionary(run_length(16),continued_fractions(co_binary)))": 251,
"opt(dictionary(run_length(16),continued_fractions(dichotomic)))": 243,
"opt(dictionary(run_length(16),heuristic(use_first(halving,approximation))))": 245,
"opt(dictionary(run_length(16),heuristic(use_first(halving,delta_largest))))": 249,
"opt(dictionary(run_length(32),continued_fractions(binary)))": 260,
"opt(dictionary(run_length(32),continued_fractions(co_binary)))": 260,
"opt(dictionary(run_length(32),continued_fractions(dichotomic)))": 238,
"opt(dictionary(run_length(32),heuristic(use_first(halving,approximation))))": 246,
"opt(dictionary(run_length(32),heuristic(use_first(halving,delta_largest))))": 258,
"opt(dictionary(run_length(64),continued_fractions(binary)))": 259,
"opt(dictionary(run_length(64),continued_fractions(co_binary)))": 259,
"opt(dictionary(run_length(64),continued_fractions(dichotomic)))": 237,
"opt(dictionary(run_length(64),heuristic(use_first(halving,approximation))))": 245,
"opt(dictionary(run_length(64),heuristic(use_first(halving,delta_largest))))": 257,
"opt(dictionary(sliding_window(128),continued_fractions(binary)))": 240,
"opt(dictionary(sliding_window(128),continued_fractions(co_binary)))": 240,
"opt(dictionary(sliding_window(128),continued_fractions(dichotomic)))": 235,
"opt(dictionary(sliding_window(128),heuristic(use_first(halving,approximation))))": 240,
"opt(dictionary(sliding_window(128),heuristic(use_first(halving,delta_largest))))": 288,
"opt(dictionary(sliding_window(16),continued_fractions(binary)))": 251,
"opt(dictionary(sliding_window(16),continued_fractions(co_binary)))": 251,
"opt(dictionary(sliding_window(16),continued_fractions(dichotomic)))": 243,
"opt(dictionary(sliding_window(16),heuristic(use_first(halving,approximation))))": 245,
"opt(dictionary(sliding_window(16),heuristic(use_first(halving,delta_largest))))": 249,
"opt(dictionary(sliding_window(32),continued_fractions(binary)))": 260,
"opt(dictionary(sliding_window(32),continued_fractions(co_binary)))": 260,
"opt(dictionary(sliding_window(32),continued_fractions(dichotomic)))": 238,
"opt(dictionary(sliding_window(32),heuristic(use_first(halving,approximation))))": 246,
"opt(dictionary(sliding_window(32),heuristic(use_first(halving,delta_largest))))": 258,
"opt(dictionary(sliding_window(4),continued_fractions(binary)))": 281,
"opt(dictionary(sliding_window(4),continued_fractions(co_binary)))": 281,
"opt(dictionary(sliding_window(4),continued_fractions(dichotomic)))": 281,
"opt(dictionary(sliding_window(4),heuristic(use_first(halving,approximation))))": 281,
"opt(dictionary(sliding_window(4),heuristic(use_first(halving,delta_largest))))": 281,
"opt(dictionary(sliding_window(64),continued_fractions(binary)))": 259,
"opt(dictionary(sliding_window(64),continued_fractions(co_binary)))": 259,
"opt(dictionary(sliding_window(64),continued_fractions(dichotomic)))": 237,
"opt(dictionary(sliding_window(64),heuristic(use_first(halving,approximation))))": 245,
"opt(dictionary(sliding_window(64),heuristic(use_first(halving,delta_largest))))": 257,
"opt(dictionary(sliding_window(8),continued_fractions(binary)))": 257,
"opt(dictionary(sliding_window(8),continued_fractions(co_binary)))": 257,
"opt(dictionary(sliding_window(8),continued_fractions(dichotomic)))": 255,
"opt(dictionary(sliding_window(8),heuristic(use_first(halving,approximation))))": 255,
"opt(dictionary(sliding_window(8),heuristic(use_first(halving,delta_largest))))": 255,
"opt(runs(continued_fractions(binary)))": 235,
"opt(runs(continued_fractions(co_binary)))": 235,
"opt(runs(continued_fractions(dichotomic)))": 235,
"opt(runs(heuristic(use_first(halving,approximation))))": 234,
"opt(runs(heuristic(use_first(halving,delta_largest))))": 234
} addchain-0.4.0/alg/ensemble/testdata/p2519_field.golden 0000664 0000000 0000000 00000035321 15143052566 0022544 0 ustar 00root root 0000000 0000000 {
"opt(dictionary(hybrid(2,0),continued_fractions(binary)))": 498,
"opt(dictionary(hybrid(2,0),continued_fractions(co_binary)))": 498,
"opt(dictionary(hybrid(2,0),continued_fractions(dichotomic)))": 265,
"opt(dictionary(hybrid(2,0),heuristic(use_first(halving,approximation))))": 376,
"opt(dictionary(hybrid(2,0),heuristic(use_first(halving,delta_largest))))": 496,
"opt(dictionary(hybrid(2,16),continued_fractions(binary)))": 273,
"opt(dictionary(hybrid(2,16),continued_fractions(co_binary)))": 273,
"opt(dictionary(hybrid(2,16),continued_fractions(dichotomic)))": 273,
"opt(dictionary(hybrid(2,16),heuristic(use_first(halving,approximation))))": 273,
"opt(dictionary(hybrid(2,16),heuristic(use_first(halving,delta_largest))))": 275,
"opt(dictionary(hybrid(2,32),continued_fractions(binary)))": 267,
"opt(dictionary(hybrid(2,32),continued_fractions(co_binary)))": 267,
"opt(dictionary(hybrid(2,32),continued_fractions(dichotomic)))": 266,
"opt(dictionary(hybrid(2,32),heuristic(use_first(halving,approximation))))": 266,
"opt(dictionary(hybrid(2,32),heuristic(use_first(halving,delta_largest))))": 271,
"opt(dictionary(hybrid(2,64),continued_fractions(binary)))": 270,
"opt(dictionary(hybrid(2,64),continued_fractions(co_binary)))": 270,
"opt(dictionary(hybrid(2,64),continued_fractions(dichotomic)))": 264,
"opt(dictionary(hybrid(2,64),heuristic(use_first(halving,approximation))))": 267,
"opt(dictionary(hybrid(2,64),heuristic(use_first(halving,delta_largest))))": 298,
"opt(dictionary(hybrid(3,0),continued_fractions(binary)))": 375,
"opt(dictionary(hybrid(3,0),continued_fractions(co_binary)))": 375,
"opt(dictionary(hybrid(3,0),continued_fractions(dichotomic)))": 264,
"opt(dictionary(hybrid(3,0),heuristic(use_first(halving,approximation))))": 335,
"opt(dictionary(hybrid(3,0),heuristic(use_first(halving,delta_largest))))": 495,
"opt(dictionary(hybrid(3,16),continued_fractions(binary)))": 272,
"opt(dictionary(hybrid(3,16),continued_fractions(co_binary)))": 272,
"opt(dictionary(hybrid(3,16),continued_fractions(dichotomic)))": 272,
"opt(dictionary(hybrid(3,16),heuristic(use_first(halving,approximation))))": 272,
"opt(dictionary(hybrid(3,16),heuristic(use_first(halving,delta_largest))))": 274,
"opt(dictionary(hybrid(3,32),continued_fractions(binary)))": 265,
"opt(dictionary(hybrid(3,32),continued_fractions(co_binary)))": 265,
"opt(dictionary(hybrid(3,32),continued_fractions(dichotomic)))": 265,
"opt(dictionary(hybrid(3,32),heuristic(use_first(halving,approximation))))": 266,
"opt(dictionary(hybrid(3,32),heuristic(use_first(halving,delta_largest))))": 270,
"opt(dictionary(hybrid(3,64),continued_fractions(binary)))": 266,
"opt(dictionary(hybrid(3,64),continued_fractions(co_binary)))": 266,
"opt(dictionary(hybrid(3,64),continued_fractions(dichotomic)))": 263,
"opt(dictionary(hybrid(3,64),heuristic(use_first(halving,approximation))))": 265,
"opt(dictionary(hybrid(3,64),heuristic(use_first(halving,delta_largest))))": 299,
"opt(dictionary(hybrid(4,0),continued_fractions(binary)))": 375,
"opt(dictionary(hybrid(4,0),continued_fractions(co_binary)))": 375,
"opt(dictionary(hybrid(4,0),continued_fractions(dichotomic)))": 264,
"opt(dictionary(hybrid(4,0),heuristic(use_first(halving,approximation))))": 335,
"opt(dictionary(hybrid(4,0),heuristic(use_first(halving,delta_largest))))": 495,
"opt(dictionary(hybrid(4,16),continued_fractions(binary)))": 272,
"opt(dictionary(hybrid(4,16),continued_fractions(co_binary)))": 272,
"opt(dictionary(hybrid(4,16),continued_fractions(dichotomic)))": 272,
"opt(dictionary(hybrid(4,16),heuristic(use_first(halving,approximation))))": 272,
"opt(dictionary(hybrid(4,16),heuristic(use_first(halving,delta_largest))))": 274,
"opt(dictionary(hybrid(4,32),continued_fractions(binary)))": 265,
"opt(dictionary(hybrid(4,32),continued_fractions(co_binary)))": 265,
"opt(dictionary(hybrid(4,32),continued_fractions(dichotomic)))": 265,
"opt(dictionary(hybrid(4,32),heuristic(use_first(halving,approximation))))": 266,
"opt(dictionary(hybrid(4,32),heuristic(use_first(halving,delta_largest))))": 270,
"opt(dictionary(hybrid(4,64),continued_fractions(binary)))": 266,
"opt(dictionary(hybrid(4,64),continued_fractions(co_binary)))": 266,
"opt(dictionary(hybrid(4,64),continued_fractions(dichotomic)))": 263,
"opt(dictionary(hybrid(4,64),heuristic(use_first(halving,approximation))))": 265,
"opt(dictionary(hybrid(4,64),heuristic(use_first(halving,delta_largest))))": 299,
"opt(dictionary(hybrid(5,0),continued_fractions(binary)))": 375,
"opt(dictionary(hybrid(5,0),continued_fractions(co_binary)))": 375,
"opt(dictionary(hybrid(5,0),continued_fractions(dichotomic)))": 264,
"opt(dictionary(hybrid(5,0),heuristic(use_first(halving,approximation))))": 335,
"opt(dictionary(hybrid(5,0),heuristic(use_first(halving,delta_largest))))": 495,
"opt(dictionary(hybrid(5,16),continued_fractions(binary)))": 272,
"opt(dictionary(hybrid(5,16),continued_fractions(co_binary)))": 272,
"opt(dictionary(hybrid(5,16),continued_fractions(dichotomic)))": 272,
"opt(dictionary(hybrid(5,16),heuristic(use_first(halving,approximation))))": 272,
"opt(dictionary(hybrid(5,16),heuristic(use_first(halving,delta_largest))))": 274,
"opt(dictionary(hybrid(5,32),continued_fractions(binary)))": 265,
"opt(dictionary(hybrid(5,32),continued_fractions(co_binary)))": 265,
"opt(dictionary(hybrid(5,32),continued_fractions(dichotomic)))": 265,
"opt(dictionary(hybrid(5,32),heuristic(use_first(halving,approximation))))": 266,
"opt(dictionary(hybrid(5,32),heuristic(use_first(halving,delta_largest))))": 270,
"opt(dictionary(hybrid(5,64),continued_fractions(binary)))": 266,
"opt(dictionary(hybrid(5,64),continued_fractions(co_binary)))": 266,
"opt(dictionary(hybrid(5,64),continued_fractions(dichotomic)))": 263,
"opt(dictionary(hybrid(5,64),heuristic(use_first(halving,approximation))))": 265,
"opt(dictionary(hybrid(5,64),heuristic(use_first(halving,delta_largest))))": 299,
"opt(dictionary(hybrid(6,0),continued_fractions(binary)))": 375,
"opt(dictionary(hybrid(6,0),continued_fractions(co_binary)))": 375,
"opt(dictionary(hybrid(6,0),continued_fractions(dichotomic)))": 264,
"opt(dictionary(hybrid(6,0),heuristic(use_first(halving,approximation))))": 335,
"opt(dictionary(hybrid(6,0),heuristic(use_first(halving,delta_largest))))": 495,
"opt(dictionary(hybrid(6,16),continued_fractions(binary)))": 272,
"opt(dictionary(hybrid(6,16),continued_fractions(co_binary)))": 272,
"opt(dictionary(hybrid(6,16),continued_fractions(dichotomic)))": 272,
"opt(dictionary(hybrid(6,16),heuristic(use_first(halving,approximation))))": 272,
"opt(dictionary(hybrid(6,16),heuristic(use_first(halving,delta_largest))))": 274,
"opt(dictionary(hybrid(6,32),continued_fractions(binary)))": 265,
"opt(dictionary(hybrid(6,32),continued_fractions(co_binary)))": 265,
"opt(dictionary(hybrid(6,32),continued_fractions(dichotomic)))": 265,
"opt(dictionary(hybrid(6,32),heuristic(use_first(halving,approximation))))": 266,
"opt(dictionary(hybrid(6,32),heuristic(use_first(halving,delta_largest))))": 270,
"opt(dictionary(hybrid(6,64),continued_fractions(binary)))": 266,
"opt(dictionary(hybrid(6,64),continued_fractions(co_binary)))": 266,
"opt(dictionary(hybrid(6,64),continued_fractions(dichotomic)))": 263,
"opt(dictionary(hybrid(6,64),heuristic(use_first(halving,approximation))))": 265,
"opt(dictionary(hybrid(6,64),heuristic(use_first(halving,delta_largest))))": 299,
"opt(dictionary(hybrid(7,0),continued_fractions(binary)))": 375,
"opt(dictionary(hybrid(7,0),continued_fractions(co_binary)))": 375,
"opt(dictionary(hybrid(7,0),continued_fractions(dichotomic)))": 264,
"opt(dictionary(hybrid(7,0),heuristic(use_first(halving,approximation))))": 335,
"opt(dictionary(hybrid(7,0),heuristic(use_first(halving,delta_largest))))": 495,
"opt(dictionary(hybrid(7,16),continued_fractions(binary)))": 272,
"opt(dictionary(hybrid(7,16),continued_fractions(co_binary)))": 272,
"opt(dictionary(hybrid(7,16),continued_fractions(dichotomic)))": 272,
"opt(dictionary(hybrid(7,16),heuristic(use_first(halving,approximation))))": 272,
"opt(dictionary(hybrid(7,16),heuristic(use_first(halving,delta_largest))))": 274,
"opt(dictionary(hybrid(7,32),continued_fractions(binary)))": 265,
"opt(dictionary(hybrid(7,32),continued_fractions(co_binary)))": 265,
"opt(dictionary(hybrid(7,32),continued_fractions(dichotomic)))": 265,
"opt(dictionary(hybrid(7,32),heuristic(use_first(halving,approximation))))": 266,
"opt(dictionary(hybrid(7,32),heuristic(use_first(halving,delta_largest))))": 270,
"opt(dictionary(hybrid(7,64),continued_fractions(binary)))": 266,
"opt(dictionary(hybrid(7,64),continued_fractions(co_binary)))": 266,
"opt(dictionary(hybrid(7,64),continued_fractions(dichotomic)))": 263,
"opt(dictionary(hybrid(7,64),heuristic(use_first(halving,approximation))))": 265,
"opt(dictionary(hybrid(7,64),heuristic(use_first(halving,delta_largest))))": 299,
"opt(dictionary(hybrid(8,0),continued_fractions(binary)))": 375,
"opt(dictionary(hybrid(8,0),continued_fractions(co_binary)))": 375,
"opt(dictionary(hybrid(8,0),continued_fractions(dichotomic)))": 264,
"opt(dictionary(hybrid(8,0),heuristic(use_first(halving,approximation))))": 335,
"opt(dictionary(hybrid(8,0),heuristic(use_first(halving,delta_largest))))": 495,
"opt(dictionary(hybrid(8,16),continued_fractions(binary)))": 272,
"opt(dictionary(hybrid(8,16),continued_fractions(co_binary)))": 272,
"opt(dictionary(hybrid(8,16),continued_fractions(dichotomic)))": 272,
"opt(dictionary(hybrid(8,16),heuristic(use_first(halving,approximation))))": 272,
"opt(dictionary(hybrid(8,16),heuristic(use_first(halving,delta_largest))))": 274,
"opt(dictionary(hybrid(8,32),continued_fractions(binary)))": 265,
"opt(dictionary(hybrid(8,32),continued_fractions(co_binary)))": 265,
"opt(dictionary(hybrid(8,32),continued_fractions(dichotomic)))": 265,
"opt(dictionary(hybrid(8,32),heuristic(use_first(halving,approximation))))": 266,
"opt(dictionary(hybrid(8,32),heuristic(use_first(halving,delta_largest))))": 270,
"opt(dictionary(hybrid(8,64),continued_fractions(binary)))": 266,
"opt(dictionary(hybrid(8,64),continued_fractions(co_binary)))": 266,
"opt(dictionary(hybrid(8,64),continued_fractions(dichotomic)))": 263,
"opt(dictionary(hybrid(8,64),heuristic(use_first(halving,approximation))))": 265,
"opt(dictionary(hybrid(8,64),heuristic(use_first(halving,delta_largest))))": 299,
"opt(dictionary(run_length(0),continued_fractions(binary)))": 498,
"opt(dictionary(run_length(0),continued_fractions(co_binary)))": 498,
"opt(dictionary(run_length(0),continued_fractions(dichotomic)))": 265,
"opt(dictionary(run_length(0),heuristic(use_first(halving,approximation))))": 376,
"opt(dictionary(run_length(0),heuristic(use_first(halving,delta_largest))))": 496,
"opt(dictionary(run_length(128),continued_fractions(binary)))": 272,
"opt(dictionary(run_length(128),continued_fractions(co_binary)))": 272,
"opt(dictionary(run_length(128),continued_fractions(dichotomic)))": 264,
"opt(dictionary(run_length(128),heuristic(use_first(halving,approximation))))": 272,
"opt(dictionary(run_length(128),heuristic(use_first(halving,delta_largest))))": 361,
"opt(dictionary(run_length(16),continued_fractions(binary)))": 273,
"opt(dictionary(run_length(16),continued_fractions(co_binary)))": 273,
"opt(dictionary(run_length(16),continued_fractions(dichotomic)))": 273,
"opt(dictionary(run_length(16),heuristic(use_first(halving,approximation))))": 273,
"opt(dictionary(run_length(16),heuristic(use_first(halving,delta_largest))))": 275,
"opt(dictionary(run_length(32),continued_fractions(binary)))": 267,
"opt(dictionary(run_length(32),continued_fractions(co_binary)))": 267,
"opt(dictionary(run_length(32),continued_fractions(dichotomic)))": 266,
"opt(dictionary(run_length(32),heuristic(use_first(halving,approximation))))": 266,
"opt(dictionary(run_length(32),heuristic(use_first(halving,delta_largest))))": 271,
"opt(dictionary(run_length(64),continued_fractions(binary)))": 270,
"opt(dictionary(run_length(64),continued_fractions(co_binary)))": 270,
"opt(dictionary(run_length(64),continued_fractions(dichotomic)))": 264,
"opt(dictionary(run_length(64),heuristic(use_first(halving,approximation))))": 267,
"opt(dictionary(run_length(64),heuristic(use_first(halving,delta_largest))))": 298,
"opt(dictionary(sliding_window(128),continued_fractions(binary)))": 306,
"opt(dictionary(sliding_window(128),continued_fractions(co_binary)))": 306,
"opt(dictionary(sliding_window(128),continued_fractions(dichotomic)))": 283,
"opt(dictionary(sliding_window(128),heuristic(use_first(halving,approximation))))": 283,
"opt(dictionary(sliding_window(128),heuristic(use_first(halving,delta_largest))))": 371,
"opt(dictionary(sliding_window(16),continued_fractions(binary)))": 273,
"opt(dictionary(sliding_window(16),continued_fractions(co_binary)))": 273,
"opt(dictionary(sliding_window(16),continued_fractions(dichotomic)))": 273,
"opt(dictionary(sliding_window(16),heuristic(use_first(halving,approximation))))": 273,
"opt(dictionary(sliding_window(16),heuristic(use_first(halving,delta_largest))))": 273,
"opt(dictionary(sliding_window(32),continued_fractions(binary)))": 273,
"opt(dictionary(sliding_window(32),continued_fractions(co_binary)))": 273,
"opt(dictionary(sliding_window(32),continued_fractions(dichotomic)))": 269,
"opt(dictionary(sliding_window(32),heuristic(use_first(halving,approximation))))": 269,
"opt(dictionary(sliding_window(32),heuristic(use_first(halving,delta_largest))))": 281,
"opt(dictionary(sliding_window(4),continued_fractions(binary)))": 315,
"opt(dictionary(sliding_window(4),continued_fractions(co_binary)))": 315,
"opt(dictionary(sliding_window(4),continued_fractions(dichotomic)))": 315,
"opt(dictionary(sliding_window(4),heuristic(use_first(halving,approximation))))": 315,
"opt(dictionary(sliding_window(4),heuristic(use_first(halving,delta_largest))))": 315,
"opt(dictionary(sliding_window(64),continued_fractions(binary)))": 284,
"opt(dictionary(sliding_window(64),continued_fractions(co_binary)))": 284,
"opt(dictionary(sliding_window(64),continued_fractions(dichotomic)))": 272,
"opt(dictionary(sliding_window(64),heuristic(use_first(halving,approximation))))": 269,
"opt(dictionary(sliding_window(64),heuristic(use_first(halving,delta_largest))))": 307,
"opt(dictionary(sliding_window(8),continued_fractions(binary)))": 286,
"opt(dictionary(sliding_window(8),continued_fractions(co_binary)))": 286,
"opt(dictionary(sliding_window(8),continued_fractions(dichotomic)))": 286,
"opt(dictionary(sliding_window(8),heuristic(use_first(halving,approximation))))": 286,
"opt(dictionary(sliding_window(8),heuristic(use_first(halving,delta_largest))))": 287,
"opt(runs(continued_fractions(binary)))": 265,
"opt(runs(continued_fractions(co_binary)))": 265,
"opt(runs(continued_fractions(dichotomic)))": 263,
"opt(runs(heuristic(use_first(halving,approximation))))": 263,
"opt(runs(heuristic(use_first(halving,delta_largest))))": 266
} addchain-0.4.0/alg/ensemble/testdata/p256_field.golden 0000664 0000000 0000000 00000035321 15143052566 0022460 0 ustar 00root root 0000000 0000000 {
"opt(dictionary(hybrid(2,0),continued_fractions(binary)))": 275,
"opt(dictionary(hybrid(2,0),continued_fractions(co_binary)))": 275,
"opt(dictionary(hybrid(2,0),continued_fractions(dichotomic)))": 267,
"opt(dictionary(hybrid(2,0),heuristic(use_first(halving,approximation))))": 275,
"opt(dictionary(hybrid(2,0),heuristic(use_first(halving,delta_largest))))": 314,
"opt(dictionary(hybrid(2,16),continued_fractions(binary)))": 271,
"opt(dictionary(hybrid(2,16),continued_fractions(co_binary)))": 271,
"opt(dictionary(hybrid(2,16),continued_fractions(dichotomic)))": 269,
"opt(dictionary(hybrid(2,16),heuristic(use_first(halving,approximation))))": 271,
"opt(dictionary(hybrid(2,16),heuristic(use_first(halving,delta_largest))))": 274,
"opt(dictionary(hybrid(2,32),continued_fractions(binary)))": 275,
"opt(dictionary(hybrid(2,32),continued_fractions(co_binary)))": 275,
"opt(dictionary(hybrid(2,32),continued_fractions(dichotomic)))": 267,
"opt(dictionary(hybrid(2,32),heuristic(use_first(halving,approximation))))": 275,
"opt(dictionary(hybrid(2,32),heuristic(use_first(halving,delta_largest))))": 286,
"opt(dictionary(hybrid(2,64),continued_fractions(binary)))": 275,
"opt(dictionary(hybrid(2,64),continued_fractions(co_binary)))": 275,
"opt(dictionary(hybrid(2,64),continued_fractions(dichotomic)))": 267,
"opt(dictionary(hybrid(2,64),heuristic(use_first(halving,approximation))))": 275,
"opt(dictionary(hybrid(2,64),heuristic(use_first(halving,delta_largest))))": 286,
"opt(dictionary(hybrid(3,0),continued_fractions(binary)))": 275,
"opt(dictionary(hybrid(3,0),continued_fractions(co_binary)))": 275,
"opt(dictionary(hybrid(3,0),continued_fractions(dichotomic)))": 267,
"opt(dictionary(hybrid(3,0),heuristic(use_first(halving,approximation))))": 275,
"opt(dictionary(hybrid(3,0),heuristic(use_first(halving,delta_largest))))": 314,
"opt(dictionary(hybrid(3,16),continued_fractions(binary)))": 271,
"opt(dictionary(hybrid(3,16),continued_fractions(co_binary)))": 271,
"opt(dictionary(hybrid(3,16),continued_fractions(dichotomic)))": 269,
"opt(dictionary(hybrid(3,16),heuristic(use_first(halving,approximation))))": 271,
"opt(dictionary(hybrid(3,16),heuristic(use_first(halving,delta_largest))))": 274,
"opt(dictionary(hybrid(3,32),continued_fractions(binary)))": 275,
"opt(dictionary(hybrid(3,32),continued_fractions(co_binary)))": 275,
"opt(dictionary(hybrid(3,32),continued_fractions(dichotomic)))": 267,
"opt(dictionary(hybrid(3,32),heuristic(use_first(halving,approximation))))": 275,
"opt(dictionary(hybrid(3,32),heuristic(use_first(halving,delta_largest))))": 286,
"opt(dictionary(hybrid(3,64),continued_fractions(binary)))": 275,
"opt(dictionary(hybrid(3,64),continued_fractions(co_binary)))": 275,
"opt(dictionary(hybrid(3,64),continued_fractions(dichotomic)))": 267,
"opt(dictionary(hybrid(3,64),heuristic(use_first(halving,approximation))))": 275,
"opt(dictionary(hybrid(3,64),heuristic(use_first(halving,delta_largest))))": 286,
"opt(dictionary(hybrid(4,0),continued_fractions(binary)))": 275,
"opt(dictionary(hybrid(4,0),continued_fractions(co_binary)))": 275,
"opt(dictionary(hybrid(4,0),continued_fractions(dichotomic)))": 267,
"opt(dictionary(hybrid(4,0),heuristic(use_first(halving,approximation))))": 275,
"opt(dictionary(hybrid(4,0),heuristic(use_first(halving,delta_largest))))": 314,
"opt(dictionary(hybrid(4,16),continued_fractions(binary)))": 271,
"opt(dictionary(hybrid(4,16),continued_fractions(co_binary)))": 271,
"opt(dictionary(hybrid(4,16),continued_fractions(dichotomic)))": 269,
"opt(dictionary(hybrid(4,16),heuristic(use_first(halving,approximation))))": 271,
"opt(dictionary(hybrid(4,16),heuristic(use_first(halving,delta_largest))))": 274,
"opt(dictionary(hybrid(4,32),continued_fractions(binary)))": 275,
"opt(dictionary(hybrid(4,32),continued_fractions(co_binary)))": 275,
"opt(dictionary(hybrid(4,32),continued_fractions(dichotomic)))": 267,
"opt(dictionary(hybrid(4,32),heuristic(use_first(halving,approximation))))": 275,
"opt(dictionary(hybrid(4,32),heuristic(use_first(halving,delta_largest))))": 286,
"opt(dictionary(hybrid(4,64),continued_fractions(binary)))": 275,
"opt(dictionary(hybrid(4,64),continued_fractions(co_binary)))": 275,
"opt(dictionary(hybrid(4,64),continued_fractions(dichotomic)))": 267,
"opt(dictionary(hybrid(4,64),heuristic(use_first(halving,approximation))))": 275,
"opt(dictionary(hybrid(4,64),heuristic(use_first(halving,delta_largest))))": 286,
"opt(dictionary(hybrid(5,0),continued_fractions(binary)))": 275,
"opt(dictionary(hybrid(5,0),continued_fractions(co_binary)))": 275,
"opt(dictionary(hybrid(5,0),continued_fractions(dichotomic)))": 267,
"opt(dictionary(hybrid(5,0),heuristic(use_first(halving,approximation))))": 275,
"opt(dictionary(hybrid(5,0),heuristic(use_first(halving,delta_largest))))": 314,
"opt(dictionary(hybrid(5,16),continued_fractions(binary)))": 271,
"opt(dictionary(hybrid(5,16),continued_fractions(co_binary)))": 271,
"opt(dictionary(hybrid(5,16),continued_fractions(dichotomic)))": 269,
"opt(dictionary(hybrid(5,16),heuristic(use_first(halving,approximation))))": 271,
"opt(dictionary(hybrid(5,16),heuristic(use_first(halving,delta_largest))))": 274,
"opt(dictionary(hybrid(5,32),continued_fractions(binary)))": 275,
"opt(dictionary(hybrid(5,32),continued_fractions(co_binary)))": 275,
"opt(dictionary(hybrid(5,32),continued_fractions(dichotomic)))": 267,
"opt(dictionary(hybrid(5,32),heuristic(use_first(halving,approximation))))": 275,
"opt(dictionary(hybrid(5,32),heuristic(use_first(halving,delta_largest))))": 286,
"opt(dictionary(hybrid(5,64),continued_fractions(binary)))": 275,
"opt(dictionary(hybrid(5,64),continued_fractions(co_binary)))": 275,
"opt(dictionary(hybrid(5,64),continued_fractions(dichotomic)))": 267,
"opt(dictionary(hybrid(5,64),heuristic(use_first(halving,approximation))))": 275,
"opt(dictionary(hybrid(5,64),heuristic(use_first(halving,delta_largest))))": 286,
"opt(dictionary(hybrid(6,0),continued_fractions(binary)))": 275,
"opt(dictionary(hybrid(6,0),continued_fractions(co_binary)))": 275,
"opt(dictionary(hybrid(6,0),continued_fractions(dichotomic)))": 267,
"opt(dictionary(hybrid(6,0),heuristic(use_first(halving,approximation))))": 275,
"opt(dictionary(hybrid(6,0),heuristic(use_first(halving,delta_largest))))": 314,
"opt(dictionary(hybrid(6,16),continued_fractions(binary)))": 271,
"opt(dictionary(hybrid(6,16),continued_fractions(co_binary)))": 271,
"opt(dictionary(hybrid(6,16),continued_fractions(dichotomic)))": 269,
"opt(dictionary(hybrid(6,16),heuristic(use_first(halving,approximation))))": 271,
"opt(dictionary(hybrid(6,16),heuristic(use_first(halving,delta_largest))))": 274,
"opt(dictionary(hybrid(6,32),continued_fractions(binary)))": 275,
"opt(dictionary(hybrid(6,32),continued_fractions(co_binary)))": 275,
"opt(dictionary(hybrid(6,32),continued_fractions(dichotomic)))": 267,
"opt(dictionary(hybrid(6,32),heuristic(use_first(halving,approximation))))": 275,
"opt(dictionary(hybrid(6,32),heuristic(use_first(halving,delta_largest))))": 286,
"opt(dictionary(hybrid(6,64),continued_fractions(binary)))": 275,
"opt(dictionary(hybrid(6,64),continued_fractions(co_binary)))": 275,
"opt(dictionary(hybrid(6,64),continued_fractions(dichotomic)))": 267,
"opt(dictionary(hybrid(6,64),heuristic(use_first(halving,approximation))))": 275,
"opt(dictionary(hybrid(6,64),heuristic(use_first(halving,delta_largest))))": 286,
"opt(dictionary(hybrid(7,0),continued_fractions(binary)))": 275,
"opt(dictionary(hybrid(7,0),continued_fractions(co_binary)))": 275,
"opt(dictionary(hybrid(7,0),continued_fractions(dichotomic)))": 267,
"opt(dictionary(hybrid(7,0),heuristic(use_first(halving,approximation))))": 275,
"opt(dictionary(hybrid(7,0),heuristic(use_first(halving,delta_largest))))": 314,
"opt(dictionary(hybrid(7,16),continued_fractions(binary)))": 271,
"opt(dictionary(hybrid(7,16),continued_fractions(co_binary)))": 271,
"opt(dictionary(hybrid(7,16),continued_fractions(dichotomic)))": 269,
"opt(dictionary(hybrid(7,16),heuristic(use_first(halving,approximation))))": 271,
"opt(dictionary(hybrid(7,16),heuristic(use_first(halving,delta_largest))))": 274,
"opt(dictionary(hybrid(7,32),continued_fractions(binary)))": 275,
"opt(dictionary(hybrid(7,32),continued_fractions(co_binary)))": 275,
"opt(dictionary(hybrid(7,32),continued_fractions(dichotomic)))": 267,
"opt(dictionary(hybrid(7,32),heuristic(use_first(halving,approximation))))": 275,
"opt(dictionary(hybrid(7,32),heuristic(use_first(halving,delta_largest))))": 286,
"opt(dictionary(hybrid(7,64),continued_fractions(binary)))": 275,
"opt(dictionary(hybrid(7,64),continued_fractions(co_binary)))": 275,
"opt(dictionary(hybrid(7,64),continued_fractions(dichotomic)))": 267,
"opt(dictionary(hybrid(7,64),heuristic(use_first(halving,approximation))))": 275,
"opt(dictionary(hybrid(7,64),heuristic(use_first(halving,delta_largest))))": 286,
"opt(dictionary(hybrid(8,0),continued_fractions(binary)))": 275,
"opt(dictionary(hybrid(8,0),continued_fractions(co_binary)))": 275,
"opt(dictionary(hybrid(8,0),continued_fractions(dichotomic)))": 267,
"opt(dictionary(hybrid(8,0),heuristic(use_first(halving,approximation))))": 275,
"opt(dictionary(hybrid(8,0),heuristic(use_first(halving,delta_largest))))": 314,
"opt(dictionary(hybrid(8,16),continued_fractions(binary)))": 271,
"opt(dictionary(hybrid(8,16),continued_fractions(co_binary)))": 271,
"opt(dictionary(hybrid(8,16),continued_fractions(dichotomic)))": 269,
"opt(dictionary(hybrid(8,16),heuristic(use_first(halving,approximation))))": 271,
"opt(dictionary(hybrid(8,16),heuristic(use_first(halving,delta_largest))))": 274,
"opt(dictionary(hybrid(8,32),continued_fractions(binary)))": 275,
"opt(dictionary(hybrid(8,32),continued_fractions(co_binary)))": 275,
"opt(dictionary(hybrid(8,32),continued_fractions(dichotomic)))": 267,
"opt(dictionary(hybrid(8,32),heuristic(use_first(halving,approximation))))": 275,
"opt(dictionary(hybrid(8,32),heuristic(use_first(halving,delta_largest))))": 286,
"opt(dictionary(hybrid(8,64),continued_fractions(binary)))": 275,
"opt(dictionary(hybrid(8,64),continued_fractions(co_binary)))": 275,
"opt(dictionary(hybrid(8,64),continued_fractions(dichotomic)))": 267,
"opt(dictionary(hybrid(8,64),heuristic(use_first(halving,approximation))))": 275,
"opt(dictionary(hybrid(8,64),heuristic(use_first(halving,delta_largest))))": 286,
"opt(dictionary(run_length(0),continued_fractions(binary)))": 275,
"opt(dictionary(run_length(0),continued_fractions(co_binary)))": 275,
"opt(dictionary(run_length(0),continued_fractions(dichotomic)))": 267,
"opt(dictionary(run_length(0),heuristic(use_first(halving,approximation))))": 275,
"opt(dictionary(run_length(0),heuristic(use_first(halving,delta_largest))))": 314,
"opt(dictionary(run_length(128),continued_fractions(binary)))": 275,
"opt(dictionary(run_length(128),continued_fractions(co_binary)))": 275,
"opt(dictionary(run_length(128),continued_fractions(dichotomic)))": 267,
"opt(dictionary(run_length(128),heuristic(use_first(halving,approximation))))": 275,
"opt(dictionary(run_length(128),heuristic(use_first(halving,delta_largest))))": 314,
"opt(dictionary(run_length(16),continued_fractions(binary)))": 271,
"opt(dictionary(run_length(16),continued_fractions(co_binary)))": 271,
"opt(dictionary(run_length(16),continued_fractions(dichotomic)))": 269,
"opt(dictionary(run_length(16),heuristic(use_first(halving,approximation))))": 271,
"opt(dictionary(run_length(16),heuristic(use_first(halving,delta_largest))))": 274,
"opt(dictionary(run_length(32),continued_fractions(binary)))": 275,
"opt(dictionary(run_length(32),continued_fractions(co_binary)))": 275,
"opt(dictionary(run_length(32),continued_fractions(dichotomic)))": 267,
"opt(dictionary(run_length(32),heuristic(use_first(halving,approximation))))": 275,
"opt(dictionary(run_length(32),heuristic(use_first(halving,delta_largest))))": 286,
"opt(dictionary(run_length(64),continued_fractions(binary)))": 275,
"opt(dictionary(run_length(64),continued_fractions(co_binary)))": 275,
"opt(dictionary(run_length(64),continued_fractions(dichotomic)))": 267,
"opt(dictionary(run_length(64),heuristic(use_first(halving,approximation))))": 275,
"opt(dictionary(run_length(64),heuristic(use_first(halving,delta_largest))))": 286,
"opt(dictionary(sliding_window(128),continued_fractions(binary)))": 304,
"opt(dictionary(sliding_window(128),continued_fractions(co_binary)))": 304,
"opt(dictionary(sliding_window(128),continued_fractions(dichotomic)))": 272,
"opt(dictionary(sliding_window(128),heuristic(use_first(halving,approximation))))": 276,
"opt(dictionary(sliding_window(128),heuristic(use_first(halving,delta_largest))))": 287,
"opt(dictionary(sliding_window(16),continued_fractions(binary)))": 271,
"opt(dictionary(sliding_window(16),continued_fractions(co_binary)))": 271,
"opt(dictionary(sliding_window(16),continued_fractions(dichotomic)))": 269,
"opt(dictionary(sliding_window(16),heuristic(use_first(halving,approximation))))": 271,
"opt(dictionary(sliding_window(16),heuristic(use_first(halving,delta_largest))))": 274,
"opt(dictionary(sliding_window(32),continued_fractions(binary)))": 275,
"opt(dictionary(sliding_window(32),continued_fractions(co_binary)))": 275,
"opt(dictionary(sliding_window(32),continued_fractions(dichotomic)))": 267,
"opt(dictionary(sliding_window(32),heuristic(use_first(halving,approximation))))": 275,
"opt(dictionary(sliding_window(32),heuristic(use_first(halving,delta_largest))))": 286,
"opt(dictionary(sliding_window(4),continued_fractions(binary)))": 289,
"opt(dictionary(sliding_window(4),continued_fractions(co_binary)))": 289,
"opt(dictionary(sliding_window(4),continued_fractions(dichotomic)))": 289,
"opt(dictionary(sliding_window(4),heuristic(use_first(halving,approximation))))": 289,
"opt(dictionary(sliding_window(4),heuristic(use_first(halving,delta_largest))))": 289,
"opt(dictionary(sliding_window(64),continued_fractions(binary)))": 276,
"opt(dictionary(sliding_window(64),continued_fractions(co_binary)))": 276,
"opt(dictionary(sliding_window(64),continued_fractions(dichotomic)))": 268,
"opt(dictionary(sliding_window(64),heuristic(use_first(halving,approximation))))": 276,
"opt(dictionary(sliding_window(64),heuristic(use_first(halving,delta_largest))))": 287,
"opt(dictionary(sliding_window(8),continued_fractions(binary)))": 275,
"opt(dictionary(sliding_window(8),continued_fractions(co_binary)))": 275,
"opt(dictionary(sliding_window(8),continued_fractions(dichotomic)))": 275,
"opt(dictionary(sliding_window(8),heuristic(use_first(halving,approximation))))": 275,
"opt(dictionary(sliding_window(8),heuristic(use_first(halving,delta_largest))))": 275,
"opt(runs(continued_fractions(binary)))": 267,
"opt(runs(continued_fractions(co_binary)))": 267,
"opt(runs(continued_fractions(dichotomic)))": 266,
"opt(runs(heuristic(use_first(halving,approximation))))": 266,
"opt(runs(heuristic(use_first(halving,delta_largest))))": 266
} addchain-0.4.0/alg/ensemble/testdata/p256_scalar.golden 0000664 0000000 0000000 00000035321 15143052566 0022642 0 ustar 00root root 0000000 0000000 {
"opt(dictionary(hybrid(2,0),continued_fractions(binary)))": 300,
"opt(dictionary(hybrid(2,0),continued_fractions(co_binary)))": 300,
"opt(dictionary(hybrid(2,0),continued_fractions(dichotomic)))": 299,
"opt(dictionary(hybrid(2,0),heuristic(use_first(halving,approximation))))": 300,
"opt(dictionary(hybrid(2,0),heuristic(use_first(halving,delta_largest))))": 317,
"opt(dictionary(hybrid(2,16),continued_fractions(binary)))": 300,
"opt(dictionary(hybrid(2,16),continued_fractions(co_binary)))": 300,
"opt(dictionary(hybrid(2,16),continued_fractions(dichotomic)))": 300,
"opt(dictionary(hybrid(2,16),heuristic(use_first(halving,approximation))))": 300,
"opt(dictionary(hybrid(2,16),heuristic(use_first(halving,delta_largest))))": 303,
"opt(dictionary(hybrid(2,32),continued_fractions(binary)))": 300,
"opt(dictionary(hybrid(2,32),continued_fractions(co_binary)))": 300,
"opt(dictionary(hybrid(2,32),continued_fractions(dichotomic)))": 299,
"opt(dictionary(hybrid(2,32),heuristic(use_first(halving,approximation))))": 300,
"opt(dictionary(hybrid(2,32),heuristic(use_first(halving,delta_largest))))": 315,
"opt(dictionary(hybrid(2,64),continued_fractions(binary)))": 300,
"opt(dictionary(hybrid(2,64),continued_fractions(co_binary)))": 300,
"opt(dictionary(hybrid(2,64),continued_fractions(dichotomic)))": 299,
"opt(dictionary(hybrid(2,64),heuristic(use_first(halving,approximation))))": 300,
"opt(dictionary(hybrid(2,64),heuristic(use_first(halving,delta_largest))))": 315,
"opt(dictionary(hybrid(3,0),continued_fractions(binary)))": 296,
"opt(dictionary(hybrid(3,0),continued_fractions(co_binary)))": 296,
"opt(dictionary(hybrid(3,0),continued_fractions(dichotomic)))": 295,
"opt(dictionary(hybrid(3,0),heuristic(use_first(halving,approximation))))": 296,
"opt(dictionary(hybrid(3,0),heuristic(use_first(halving,delta_largest))))": 313,
"opt(dictionary(hybrid(3,16),continued_fractions(binary)))": 296,
"opt(dictionary(hybrid(3,16),continued_fractions(co_binary)))": 296,
"opt(dictionary(hybrid(3,16),continued_fractions(dichotomic)))": 296,
"opt(dictionary(hybrid(3,16),heuristic(use_first(halving,approximation))))": 296,
"opt(dictionary(hybrid(3,16),heuristic(use_first(halving,delta_largest))))": 299,
"opt(dictionary(hybrid(3,32),continued_fractions(binary)))": 296,
"opt(dictionary(hybrid(3,32),continued_fractions(co_binary)))": 296,
"opt(dictionary(hybrid(3,32),continued_fractions(dichotomic)))": 295,
"opt(dictionary(hybrid(3,32),heuristic(use_first(halving,approximation))))": 296,
"opt(dictionary(hybrid(3,32),heuristic(use_first(halving,delta_largest))))": 312,
"opt(dictionary(hybrid(3,64),continued_fractions(binary)))": 296,
"opt(dictionary(hybrid(3,64),continued_fractions(co_binary)))": 296,
"opt(dictionary(hybrid(3,64),continued_fractions(dichotomic)))": 295,
"opt(dictionary(hybrid(3,64),heuristic(use_first(halving,approximation))))": 296,
"opt(dictionary(hybrid(3,64),heuristic(use_first(halving,delta_largest))))": 312,
"opt(dictionary(hybrid(4,0),continued_fractions(binary)))": 296,
"opt(dictionary(hybrid(4,0),continued_fractions(co_binary)))": 296,
"opt(dictionary(hybrid(4,0),continued_fractions(dichotomic)))": 295,
"opt(dictionary(hybrid(4,0),heuristic(use_first(halving,approximation))))": 296,
"opt(dictionary(hybrid(4,0),heuristic(use_first(halving,delta_largest))))": 313,
"opt(dictionary(hybrid(4,16),continued_fractions(binary)))": 296,
"opt(dictionary(hybrid(4,16),continued_fractions(co_binary)))": 296,
"opt(dictionary(hybrid(4,16),continued_fractions(dichotomic)))": 296,
"opt(dictionary(hybrid(4,16),heuristic(use_first(halving,approximation))))": 296,
"opt(dictionary(hybrid(4,16),heuristic(use_first(halving,delta_largest))))": 300,
"opt(dictionary(hybrid(4,32),continued_fractions(binary)))": 296,
"opt(dictionary(hybrid(4,32),continued_fractions(co_binary)))": 296,
"opt(dictionary(hybrid(4,32),continued_fractions(dichotomic)))": 295,
"opt(dictionary(hybrid(4,32),heuristic(use_first(halving,approximation))))": 296,
"opt(dictionary(hybrid(4,32),heuristic(use_first(halving,delta_largest))))": 313,
"opt(dictionary(hybrid(4,64),continued_fractions(binary)))": 296,
"opt(dictionary(hybrid(4,64),continued_fractions(co_binary)))": 296,
"opt(dictionary(hybrid(4,64),continued_fractions(dichotomic)))": 295,
"opt(dictionary(hybrid(4,64),heuristic(use_first(halving,approximation))))": 296,
"opt(dictionary(hybrid(4,64),heuristic(use_first(halving,delta_largest))))": 313,
"opt(dictionary(hybrid(5,0),continued_fractions(binary)))": 297,
"opt(dictionary(hybrid(5,0),continued_fractions(co_binary)))": 297,
"opt(dictionary(hybrid(5,0),continued_fractions(dichotomic)))": 296,
"opt(dictionary(hybrid(5,0),heuristic(use_first(halving,approximation))))": 297,
"opt(dictionary(hybrid(5,0),heuristic(use_first(halving,delta_largest))))": 314,
"opt(dictionary(hybrid(5,16),continued_fractions(binary)))": 296,
"opt(dictionary(hybrid(5,16),continued_fractions(co_binary)))": 296,
"opt(dictionary(hybrid(5,16),continued_fractions(dichotomic)))": 296,
"opt(dictionary(hybrid(5,16),heuristic(use_first(halving,approximation))))": 296,
"opt(dictionary(hybrid(5,16),heuristic(use_first(halving,delta_largest))))": 299,
"opt(dictionary(hybrid(5,32),continued_fractions(binary)))": 296,
"opt(dictionary(hybrid(5,32),continued_fractions(co_binary)))": 296,
"opt(dictionary(hybrid(5,32),continued_fractions(dichotomic)))": 295,
"opt(dictionary(hybrid(5,32),heuristic(use_first(halving,approximation))))": 296,
"opt(dictionary(hybrid(5,32),heuristic(use_first(halving,delta_largest))))": 313,
"opt(dictionary(hybrid(5,64),continued_fractions(binary)))": 296,
"opt(dictionary(hybrid(5,64),continued_fractions(co_binary)))": 296,
"opt(dictionary(hybrid(5,64),continued_fractions(dichotomic)))": 295,
"opt(dictionary(hybrid(5,64),heuristic(use_first(halving,approximation))))": 296,
"opt(dictionary(hybrid(5,64),heuristic(use_first(halving,delta_largest))))": 313,
"opt(dictionary(hybrid(6,0),continued_fractions(binary)))": 303,
"opt(dictionary(hybrid(6,0),continued_fractions(co_binary)))": 303,
"opt(dictionary(hybrid(6,0),continued_fractions(dichotomic)))": 300,
"opt(dictionary(hybrid(6,0),heuristic(use_first(halving,approximation))))": 299,
"opt(dictionary(hybrid(6,0),heuristic(use_first(halving,delta_largest))))": 312,
"opt(dictionary(hybrid(6,16),continued_fractions(binary)))": 296,
"opt(dictionary(hybrid(6,16),continued_fractions(co_binary)))": 296,
"opt(dictionary(hybrid(6,16),continued_fractions(dichotomic)))": 296,
"opt(dictionary(hybrid(6,16),heuristic(use_first(halving,approximation))))": 297,
"opt(dictionary(hybrid(6,16),heuristic(use_first(halving,delta_largest))))": 299,
"opt(dictionary(hybrid(6,32),continued_fractions(binary)))": 302,
"opt(dictionary(hybrid(6,32),continued_fractions(co_binary)))": 302,
"opt(dictionary(hybrid(6,32),continued_fractions(dichotomic)))": 299,
"opt(dictionary(hybrid(6,32),heuristic(use_first(halving,approximation))))": 298,
"opt(dictionary(hybrid(6,32),heuristic(use_first(halving,delta_largest))))": 311,
"opt(dictionary(hybrid(6,64),continued_fractions(binary)))": 302,
"opt(dictionary(hybrid(6,64),continued_fractions(co_binary)))": 302,
"opt(dictionary(hybrid(6,64),continued_fractions(dichotomic)))": 299,
"opt(dictionary(hybrid(6,64),heuristic(use_first(halving,approximation))))": 298,
"opt(dictionary(hybrid(6,64),heuristic(use_first(halving,delta_largest))))": 311,
"opt(dictionary(hybrid(7,0),continued_fractions(binary)))": 304,
"opt(dictionary(hybrid(7,0),continued_fractions(co_binary)))": 304,
"opt(dictionary(hybrid(7,0),continued_fractions(dichotomic)))": 301,
"opt(dictionary(hybrid(7,0),heuristic(use_first(halving,approximation))))": 297,
"opt(dictionary(hybrid(7,0),heuristic(use_first(halving,delta_largest))))": 312,
"opt(dictionary(hybrid(7,16),continued_fractions(binary)))": 297,
"opt(dictionary(hybrid(7,16),continued_fractions(co_binary)))": 297,
"opt(dictionary(hybrid(7,16),continued_fractions(dichotomic)))": 297,
"opt(dictionary(hybrid(7,16),heuristic(use_first(halving,approximation))))": 300,
"opt(dictionary(hybrid(7,16),heuristic(use_first(halving,delta_largest))))": 299,
"opt(dictionary(hybrid(7,32),continued_fractions(binary)))": 303,
"opt(dictionary(hybrid(7,32),continued_fractions(co_binary)))": 303,
"opt(dictionary(hybrid(7,32),continued_fractions(dichotomic)))": 300,
"opt(dictionary(hybrid(7,32),heuristic(use_first(halving,approximation))))": 298,
"opt(dictionary(hybrid(7,32),heuristic(use_first(halving,delta_largest))))": 313,
"opt(dictionary(hybrid(7,64),continued_fractions(binary)))": 303,
"opt(dictionary(hybrid(7,64),continued_fractions(co_binary)))": 303,
"opt(dictionary(hybrid(7,64),continued_fractions(dichotomic)))": 300,
"opt(dictionary(hybrid(7,64),heuristic(use_first(halving,approximation))))": 298,
"opt(dictionary(hybrid(7,64),heuristic(use_first(halving,delta_largest))))": 313,
"opt(dictionary(hybrid(8,0),continued_fractions(binary)))": 303,
"opt(dictionary(hybrid(8,0),continued_fractions(co_binary)))": 303,
"opt(dictionary(hybrid(8,0),continued_fractions(dichotomic)))": 302,
"opt(dictionary(hybrid(8,0),heuristic(use_first(halving,approximation))))": 298,
"opt(dictionary(hybrid(8,0),heuristic(use_first(halving,delta_largest))))": 310,
"opt(dictionary(hybrid(8,16),continued_fractions(binary)))": 297,
"opt(dictionary(hybrid(8,16),continued_fractions(co_binary)))": 297,
"opt(dictionary(hybrid(8,16),continued_fractions(dichotomic)))": 296,
"opt(dictionary(hybrid(8,16),heuristic(use_first(halving,approximation))))": 298,
"opt(dictionary(hybrid(8,16),heuristic(use_first(halving,delta_largest))))": 294,
"opt(dictionary(hybrid(8,32),continued_fractions(binary)))": 304,
"opt(dictionary(hybrid(8,32),continued_fractions(co_binary)))": 304,
"opt(dictionary(hybrid(8,32),continued_fractions(dichotomic)))": 298,
"opt(dictionary(hybrid(8,32),heuristic(use_first(halving,approximation))))": 297,
"opt(dictionary(hybrid(8,32),heuristic(use_first(halving,delta_largest))))": 305,
"opt(dictionary(hybrid(8,64),continued_fractions(binary)))": 304,
"opt(dictionary(hybrid(8,64),continued_fractions(co_binary)))": 304,
"opt(dictionary(hybrid(8,64),continued_fractions(dichotomic)))": 298,
"opt(dictionary(hybrid(8,64),heuristic(use_first(halving,approximation))))": 297,
"opt(dictionary(hybrid(8,64),heuristic(use_first(halving,delta_largest))))": 305,
"opt(dictionary(run_length(0),continued_fractions(binary)))": 300,
"opt(dictionary(run_length(0),continued_fractions(co_binary)))": 300,
"opt(dictionary(run_length(0),continued_fractions(dichotomic)))": 299,
"opt(dictionary(run_length(0),heuristic(use_first(halving,approximation))))": 300,
"opt(dictionary(run_length(0),heuristic(use_first(halving,delta_largest))))": 317,
"opt(dictionary(run_length(128),continued_fractions(binary)))": 300,
"opt(dictionary(run_length(128),continued_fractions(co_binary)))": 300,
"opt(dictionary(run_length(128),continued_fractions(dichotomic)))": 299,
"opt(dictionary(run_length(128),heuristic(use_first(halving,approximation))))": 300,
"opt(dictionary(run_length(128),heuristic(use_first(halving,delta_largest))))": 317,
"opt(dictionary(run_length(16),continued_fractions(binary)))": 300,
"opt(dictionary(run_length(16),continued_fractions(co_binary)))": 300,
"opt(dictionary(run_length(16),continued_fractions(dichotomic)))": 300,
"opt(dictionary(run_length(16),heuristic(use_first(halving,approximation))))": 300,
"opt(dictionary(run_length(16),heuristic(use_first(halving,delta_largest))))": 303,
"opt(dictionary(run_length(32),continued_fractions(binary)))": 300,
"opt(dictionary(run_length(32),continued_fractions(co_binary)))": 300,
"opt(dictionary(run_length(32),continued_fractions(dichotomic)))": 299,
"opt(dictionary(run_length(32),heuristic(use_first(halving,approximation))))": 300,
"opt(dictionary(run_length(32),heuristic(use_first(halving,delta_largest))))": 315,
"opt(dictionary(run_length(64),continued_fractions(binary)))": 300,
"opt(dictionary(run_length(64),continued_fractions(co_binary)))": 300,
"opt(dictionary(run_length(64),continued_fractions(dichotomic)))": 299,
"opt(dictionary(run_length(64),heuristic(use_first(halving,approximation))))": 300,
"opt(dictionary(run_length(64),heuristic(use_first(halving,delta_largest))))": 315,
"opt(dictionary(sliding_window(128),continued_fractions(binary)))": 333,
"opt(dictionary(sliding_window(128),continued_fractions(co_binary)))": 333,
"opt(dictionary(sliding_window(128),continued_fractions(dichotomic)))": 332,
"opt(dictionary(sliding_window(128),heuristic(use_first(halving,approximation))))": 332,
"opt(dictionary(sliding_window(128),heuristic(use_first(halving,delta_largest))))": 332,
"opt(dictionary(sliding_window(16),continued_fractions(binary)))": 296,
"opt(dictionary(sliding_window(16),continued_fractions(co_binary)))": 296,
"opt(dictionary(sliding_window(16),continued_fractions(dichotomic)))": 296,
"opt(dictionary(sliding_window(16),heuristic(use_first(halving,approximation))))": 295,
"opt(dictionary(sliding_window(16),heuristic(use_first(halving,delta_largest))))": 296,
"opt(dictionary(sliding_window(32),continued_fractions(binary)))": 299,
"opt(dictionary(sliding_window(32),continued_fractions(co_binary)))": 299,
"opt(dictionary(sliding_window(32),continued_fractions(dichotomic)))": 299,
"opt(dictionary(sliding_window(32),heuristic(use_first(halving,approximation))))": 304,
"opt(dictionary(sliding_window(32),heuristic(use_first(halving,delta_largest))))": 300,
"opt(dictionary(sliding_window(4),continued_fractions(binary)))": 310,
"opt(dictionary(sliding_window(4),continued_fractions(co_binary)))": 310,
"opt(dictionary(sliding_window(4),continued_fractions(dichotomic)))": 310,
"opt(dictionary(sliding_window(4),heuristic(use_first(halving,approximation))))": 310,
"opt(dictionary(sliding_window(4),heuristic(use_first(halving,delta_largest))))": 310,
"opt(dictionary(sliding_window(64),continued_fractions(binary)))": 348,
"opt(dictionary(sliding_window(64),continued_fractions(co_binary)))": 348,
"opt(dictionary(sliding_window(64),continued_fractions(dichotomic)))": 348,
"opt(dictionary(sliding_window(64),heuristic(use_first(halving,approximation))))": 354,
"opt(dictionary(sliding_window(64),heuristic(use_first(halving,delta_largest))))": 349,
"opt(dictionary(sliding_window(8),continued_fractions(binary)))": 299,
"opt(dictionary(sliding_window(8),continued_fractions(co_binary)))": 299,
"opt(dictionary(sliding_window(8),continued_fractions(dichotomic)))": 299,
"opt(dictionary(sliding_window(8),heuristic(use_first(halving,approximation))))": 303,
"opt(dictionary(sliding_window(8),heuristic(use_first(halving,delta_largest))))": 299,
"opt(runs(continued_fractions(binary)))": 299,
"opt(runs(continued_fractions(co_binary)))": 299,
"opt(runs(continued_fractions(dichotomic)))": 299,
"opt(runs(heuristic(use_first(halving,approximation))))": 298,
"opt(runs(heuristic(use_first(halving,delta_largest))))": 298
} addchain-0.4.0/alg/ensemble/testdata/p382105_field.golden 0000664 0000000 0000000 00000035321 15143052566 0022706 0 ustar 00root root 0000000 0000000 {
"opt(dictionary(hybrid(2,0),continued_fractions(binary)))": 758,
"opt(dictionary(hybrid(2,0),continued_fractions(co_binary)))": 758,
"opt(dictionary(hybrid(2,0),continued_fractions(dichotomic)))": 398,
"opt(dictionary(hybrid(2,0),heuristic(use_first(halving,approximation))))": 572,
"opt(dictionary(hybrid(2,0),heuristic(use_first(halving,delta_largest))))": 756,
"opt(dictionary(hybrid(2,16),continued_fractions(binary)))": 413,
"opt(dictionary(hybrid(2,16),continued_fractions(co_binary)))": 413,
"opt(dictionary(hybrid(2,16),continued_fractions(dichotomic)))": 413,
"opt(dictionary(hybrid(2,16),heuristic(use_first(halving,approximation))))": 413,
"opt(dictionary(hybrid(2,16),heuristic(use_first(halving,delta_largest))))": 415,
"opt(dictionary(hybrid(2,32),continued_fractions(binary)))": 403,
"opt(dictionary(hybrid(2,32),continued_fractions(co_binary)))": 403,
"opt(dictionary(hybrid(2,32),continued_fractions(dichotomic)))": 402,
"opt(dictionary(hybrid(2,32),heuristic(use_first(halving,approximation))))": 402,
"opt(dictionary(hybrid(2,32),heuristic(use_first(halving,delta_largest))))": 407,
"opt(dictionary(hybrid(2,64),continued_fractions(binary)))": 404,
"opt(dictionary(hybrid(2,64),continued_fractions(co_binary)))": 404,
"opt(dictionary(hybrid(2,64),continued_fractions(dichotomic)))": 398,
"opt(dictionary(hybrid(2,64),heuristic(use_first(halving,approximation))))": 401,
"opt(dictionary(hybrid(2,64),heuristic(use_first(halving,delta_largest))))": 432,
"opt(dictionary(hybrid(3,0),continued_fractions(binary)))": 571,
"opt(dictionary(hybrid(3,0),continued_fractions(co_binary)))": 571,
"opt(dictionary(hybrid(3,0),continued_fractions(dichotomic)))": 397,
"opt(dictionary(hybrid(3,0),heuristic(use_first(halving,approximation))))": 509,
"opt(dictionary(hybrid(3,0),heuristic(use_first(halving,delta_largest))))": 753,
"opt(dictionary(hybrid(3,16),continued_fractions(binary)))": 412,
"opt(dictionary(hybrid(3,16),continued_fractions(co_binary)))": 412,
"opt(dictionary(hybrid(3,16),continued_fractions(dichotomic)))": 412,
"opt(dictionary(hybrid(3,16),heuristic(use_first(halving,approximation))))": 412,
"opt(dictionary(hybrid(3,16),heuristic(use_first(halving,delta_largest))))": 414,
"opt(dictionary(hybrid(3,32),continued_fractions(binary)))": 401,
"opt(dictionary(hybrid(3,32),continued_fractions(co_binary)))": 401,
"opt(dictionary(hybrid(3,32),continued_fractions(dichotomic)))": 401,
"opt(dictionary(hybrid(3,32),heuristic(use_first(halving,approximation))))": 402,
"opt(dictionary(hybrid(3,32),heuristic(use_first(halving,delta_largest))))": 406,
"opt(dictionary(hybrid(3,64),continued_fractions(binary)))": 400,
"opt(dictionary(hybrid(3,64),continued_fractions(co_binary)))": 400,
"opt(dictionary(hybrid(3,64),continued_fractions(dichotomic)))": 397,
"opt(dictionary(hybrid(3,64),heuristic(use_first(halving,approximation))))": 399,
"opt(dictionary(hybrid(3,64),heuristic(use_first(halving,delta_largest))))": 433,
"opt(dictionary(hybrid(4,0),continued_fractions(binary)))": 571,
"opt(dictionary(hybrid(4,0),continued_fractions(co_binary)))": 571,
"opt(dictionary(hybrid(4,0),continued_fractions(dichotomic)))": 397,
"opt(dictionary(hybrid(4,0),heuristic(use_first(halving,approximation))))": 509,
"opt(dictionary(hybrid(4,0),heuristic(use_first(halving,delta_largest))))": 753,
"opt(dictionary(hybrid(4,16),continued_fractions(binary)))": 412,
"opt(dictionary(hybrid(4,16),continued_fractions(co_binary)))": 412,
"opt(dictionary(hybrid(4,16),continued_fractions(dichotomic)))": 412,
"opt(dictionary(hybrid(4,16),heuristic(use_first(halving,approximation))))": 412,
"opt(dictionary(hybrid(4,16),heuristic(use_first(halving,delta_largest))))": 414,
"opt(dictionary(hybrid(4,32),continued_fractions(binary)))": 401,
"opt(dictionary(hybrid(4,32),continued_fractions(co_binary)))": 401,
"opt(dictionary(hybrid(4,32),continued_fractions(dichotomic)))": 401,
"opt(dictionary(hybrid(4,32),heuristic(use_first(halving,approximation))))": 402,
"opt(dictionary(hybrid(4,32),heuristic(use_first(halving,delta_largest))))": 406,
"opt(dictionary(hybrid(4,64),continued_fractions(binary)))": 400,
"opt(dictionary(hybrid(4,64),continued_fractions(co_binary)))": 400,
"opt(dictionary(hybrid(4,64),continued_fractions(dichotomic)))": 397,
"opt(dictionary(hybrid(4,64),heuristic(use_first(halving,approximation))))": 399,
"opt(dictionary(hybrid(4,64),heuristic(use_first(halving,delta_largest))))": 433,
"opt(dictionary(hybrid(5,0),continued_fractions(binary)))": 508,
"opt(dictionary(hybrid(5,0),continued_fractions(co_binary)))": 508,
"opt(dictionary(hybrid(5,0),continued_fractions(dichotomic)))": 395,
"opt(dictionary(hybrid(5,0),heuristic(use_first(halving,approximation))))": 459,
"opt(dictionary(hybrid(5,0),heuristic(use_first(halving,delta_largest))))": 749,
"opt(dictionary(hybrid(5,16),continued_fractions(binary)))": 411,
"opt(dictionary(hybrid(5,16),continued_fractions(co_binary)))": 411,
"opt(dictionary(hybrid(5,16),continued_fractions(dichotomic)))": 411,
"opt(dictionary(hybrid(5,16),heuristic(use_first(halving,approximation))))": 411,
"opt(dictionary(hybrid(5,16),heuristic(use_first(halving,delta_largest))))": 412,
"opt(dictionary(hybrid(5,32),continued_fractions(binary)))": 401,
"opt(dictionary(hybrid(5,32),continued_fractions(co_binary)))": 401,
"opt(dictionary(hybrid(5,32),continued_fractions(dichotomic)))": 401,
"opt(dictionary(hybrid(5,32),heuristic(use_first(halving,approximation))))": 402,
"opt(dictionary(hybrid(5,32),heuristic(use_first(halving,delta_largest))))": 405,
"opt(dictionary(hybrid(5,64),continued_fractions(binary)))": 398,
"opt(dictionary(hybrid(5,64),continued_fractions(co_binary)))": 398,
"opt(dictionary(hybrid(5,64),continued_fractions(dichotomic)))": 396,
"opt(dictionary(hybrid(5,64),heuristic(use_first(halving,approximation))))": 400,
"opt(dictionary(hybrid(5,64),heuristic(use_first(halving,delta_largest))))": 431,
"opt(dictionary(hybrid(6,0),continued_fractions(binary)))": 508,
"opt(dictionary(hybrid(6,0),continued_fractions(co_binary)))": 508,
"opt(dictionary(hybrid(6,0),continued_fractions(dichotomic)))": 395,
"opt(dictionary(hybrid(6,0),heuristic(use_first(halving,approximation))))": 459,
"opt(dictionary(hybrid(6,0),heuristic(use_first(halving,delta_largest))))": 749,
"opt(dictionary(hybrid(6,16),continued_fractions(binary)))": 411,
"opt(dictionary(hybrid(6,16),continued_fractions(co_binary)))": 411,
"opt(dictionary(hybrid(6,16),continued_fractions(dichotomic)))": 411,
"opt(dictionary(hybrid(6,16),heuristic(use_first(halving,approximation))))": 411,
"opt(dictionary(hybrid(6,16),heuristic(use_first(halving,delta_largest))))": 412,
"opt(dictionary(hybrid(6,32),continued_fractions(binary)))": 401,
"opt(dictionary(hybrid(6,32),continued_fractions(co_binary)))": 401,
"opt(dictionary(hybrid(6,32),continued_fractions(dichotomic)))": 401,
"opt(dictionary(hybrid(6,32),heuristic(use_first(halving,approximation))))": 402,
"opt(dictionary(hybrid(6,32),heuristic(use_first(halving,delta_largest))))": 405,
"opt(dictionary(hybrid(6,64),continued_fractions(binary)))": 398,
"opt(dictionary(hybrid(6,64),continued_fractions(co_binary)))": 398,
"opt(dictionary(hybrid(6,64),continued_fractions(dichotomic)))": 396,
"opt(dictionary(hybrid(6,64),heuristic(use_first(halving,approximation))))": 400,
"opt(dictionary(hybrid(6,64),heuristic(use_first(halving,delta_largest))))": 431,
"opt(dictionary(hybrid(7,0),continued_fractions(binary)))": 508,
"opt(dictionary(hybrid(7,0),continued_fractions(co_binary)))": 508,
"opt(dictionary(hybrid(7,0),continued_fractions(dichotomic)))": 395,
"opt(dictionary(hybrid(7,0),heuristic(use_first(halving,approximation))))": 459,
"opt(dictionary(hybrid(7,0),heuristic(use_first(halving,delta_largest))))": 749,
"opt(dictionary(hybrid(7,16),continued_fractions(binary)))": 411,
"opt(dictionary(hybrid(7,16),continued_fractions(co_binary)))": 411,
"opt(dictionary(hybrid(7,16),continued_fractions(dichotomic)))": 411,
"opt(dictionary(hybrid(7,16),heuristic(use_first(halving,approximation))))": 411,
"opt(dictionary(hybrid(7,16),heuristic(use_first(halving,delta_largest))))": 412,
"opt(dictionary(hybrid(7,32),continued_fractions(binary)))": 401,
"opt(dictionary(hybrid(7,32),continued_fractions(co_binary)))": 401,
"opt(dictionary(hybrid(7,32),continued_fractions(dichotomic)))": 401,
"opt(dictionary(hybrid(7,32),heuristic(use_first(halving,approximation))))": 402,
"opt(dictionary(hybrid(7,32),heuristic(use_first(halving,delta_largest))))": 405,
"opt(dictionary(hybrid(7,64),continued_fractions(binary)))": 398,
"opt(dictionary(hybrid(7,64),continued_fractions(co_binary)))": 398,
"opt(dictionary(hybrid(7,64),continued_fractions(dichotomic)))": 396,
"opt(dictionary(hybrid(7,64),heuristic(use_first(halving,approximation))))": 400,
"opt(dictionary(hybrid(7,64),heuristic(use_first(halving,delta_largest))))": 431,
"opt(dictionary(hybrid(8,0),continued_fractions(binary)))": 508,
"opt(dictionary(hybrid(8,0),continued_fractions(co_binary)))": 508,
"opt(dictionary(hybrid(8,0),continued_fractions(dichotomic)))": 395,
"opt(dictionary(hybrid(8,0),heuristic(use_first(halving,approximation))))": 459,
"opt(dictionary(hybrid(8,0),heuristic(use_first(halving,delta_largest))))": 749,
"opt(dictionary(hybrid(8,16),continued_fractions(binary)))": 411,
"opt(dictionary(hybrid(8,16),continued_fractions(co_binary)))": 411,
"opt(dictionary(hybrid(8,16),continued_fractions(dichotomic)))": 411,
"opt(dictionary(hybrid(8,16),heuristic(use_first(halving,approximation))))": 411,
"opt(dictionary(hybrid(8,16),heuristic(use_first(halving,delta_largest))))": 412,
"opt(dictionary(hybrid(8,32),continued_fractions(binary)))": 401,
"opt(dictionary(hybrid(8,32),continued_fractions(co_binary)))": 401,
"opt(dictionary(hybrid(8,32),continued_fractions(dichotomic)))": 401,
"opt(dictionary(hybrid(8,32),heuristic(use_first(halving,approximation))))": 402,
"opt(dictionary(hybrid(8,32),heuristic(use_first(halving,delta_largest))))": 405,
"opt(dictionary(hybrid(8,64),continued_fractions(binary)))": 398,
"opt(dictionary(hybrid(8,64),continued_fractions(co_binary)))": 398,
"opt(dictionary(hybrid(8,64),continued_fractions(dichotomic)))": 396,
"opt(dictionary(hybrid(8,64),heuristic(use_first(halving,approximation))))": 400,
"opt(dictionary(hybrid(8,64),heuristic(use_first(halving,delta_largest))))": 431,
"opt(dictionary(run_length(0),continued_fractions(binary)))": 758,
"opt(dictionary(run_length(0),continued_fractions(co_binary)))": 758,
"opt(dictionary(run_length(0),continued_fractions(dichotomic)))": 398,
"opt(dictionary(run_length(0),heuristic(use_first(halving,approximation))))": 572,
"opt(dictionary(run_length(0),heuristic(use_first(halving,delta_largest))))": 756,
"opt(dictionary(run_length(128),continued_fractions(binary)))": 405,
"opt(dictionary(run_length(128),continued_fractions(co_binary)))": 405,
"opt(dictionary(run_length(128),continued_fractions(dichotomic)))": 397,
"opt(dictionary(run_length(128),heuristic(use_first(halving,approximation))))": 405,
"opt(dictionary(run_length(128),heuristic(use_first(halving,delta_largest))))": 494,
"opt(dictionary(run_length(16),continued_fractions(binary)))": 413,
"opt(dictionary(run_length(16),continued_fractions(co_binary)))": 413,
"opt(dictionary(run_length(16),continued_fractions(dichotomic)))": 413,
"opt(dictionary(run_length(16),heuristic(use_first(halving,approximation))))": 413,
"opt(dictionary(run_length(16),heuristic(use_first(halving,delta_largest))))": 415,
"opt(dictionary(run_length(32),continued_fractions(binary)))": 403,
"opt(dictionary(run_length(32),continued_fractions(co_binary)))": 403,
"opt(dictionary(run_length(32),continued_fractions(dichotomic)))": 402,
"opt(dictionary(run_length(32),heuristic(use_first(halving,approximation))))": 402,
"opt(dictionary(run_length(32),heuristic(use_first(halving,delta_largest))))": 407,
"opt(dictionary(run_length(64),continued_fractions(binary)))": 404,
"opt(dictionary(run_length(64),continued_fractions(co_binary)))": 404,
"opt(dictionary(run_length(64),continued_fractions(dichotomic)))": 398,
"opt(dictionary(run_length(64),heuristic(use_first(halving,approximation))))": 401,
"opt(dictionary(run_length(64),heuristic(use_first(halving,delta_largest))))": 432,
"opt(dictionary(sliding_window(128),continued_fractions(binary)))": 459,
"opt(dictionary(sliding_window(128),continued_fractions(co_binary)))": 459,
"opt(dictionary(sliding_window(128),continued_fractions(dichotomic)))": 409,
"opt(dictionary(sliding_window(128),heuristic(use_first(halving,approximation))))": 407,
"opt(dictionary(sliding_window(128),heuristic(use_first(halving,delta_largest))))": 503,
"opt(dictionary(sliding_window(16),continued_fractions(binary)))": 412,
"opt(dictionary(sliding_window(16),continued_fractions(co_binary)))": 412,
"opt(dictionary(sliding_window(16),continued_fractions(dichotomic)))": 412,
"opt(dictionary(sliding_window(16),heuristic(use_first(halving,approximation))))": 412,
"opt(dictionary(sliding_window(16),heuristic(use_first(halving,delta_largest))))": 412,
"opt(dictionary(sliding_window(32),continued_fractions(binary)))": 410,
"opt(dictionary(sliding_window(32),continued_fractions(co_binary)))": 410,
"opt(dictionary(sliding_window(32),continued_fractions(dichotomic)))": 406,
"opt(dictionary(sliding_window(32),heuristic(use_first(halving,approximation))))": 405,
"opt(dictionary(sliding_window(32),heuristic(use_first(halving,delta_largest))))": 418,
"opt(dictionary(sliding_window(4),continued_fractions(binary)))": 479,
"opt(dictionary(sliding_window(4),continued_fractions(co_binary)))": 479,
"opt(dictionary(sliding_window(4),continued_fractions(dichotomic)))": 479,
"opt(dictionary(sliding_window(4),heuristic(use_first(halving,approximation))))": 479,
"opt(dictionary(sliding_window(4),heuristic(use_first(halving,delta_largest))))": 479,
"opt(dictionary(sliding_window(64),continued_fractions(binary)))": 426,
"opt(dictionary(sliding_window(64),continued_fractions(co_binary)))": 426,
"opt(dictionary(sliding_window(64),continued_fractions(dichotomic)))": 408,
"opt(dictionary(sliding_window(64),heuristic(use_first(halving,approximation))))": 406,
"opt(dictionary(sliding_window(64),heuristic(use_first(halving,delta_largest))))": 443,
"opt(dictionary(sliding_window(8),continued_fractions(binary)))": 433,
"opt(dictionary(sliding_window(8),continued_fractions(co_binary)))": 433,
"opt(dictionary(sliding_window(8),continued_fractions(dichotomic)))": 433,
"opt(dictionary(sliding_window(8),heuristic(use_first(halving,approximation))))": 433,
"opt(dictionary(sliding_window(8),heuristic(use_first(halving,delta_largest))))": 433,
"opt(runs(continued_fractions(binary)))": 398,
"opt(runs(continued_fractions(co_binary)))": 398,
"opt(runs(continued_fractions(dichotomic)))": 396,
"opt(runs(heuristic(use_first(halving,approximation))))": 398,
"opt(runs(heuristic(use_first(halving,delta_largest))))": 399
} addchain-0.4.0/alg/ensemble/testdata/p383187_field.golden 0000664 0000000 0000000 00000035321 15143052566 0022721 0 ustar 00root root 0000000 0000000 {
"opt(dictionary(hybrid(2,0),continued_fractions(binary)))": 572,
"opt(dictionary(hybrid(2,0),continued_fractions(co_binary)))": 572,
"opt(dictionary(hybrid(2,0),continued_fractions(dichotomic)))": 398,
"opt(dictionary(hybrid(2,0),heuristic(use_first(halving,approximation))))": 572,
"opt(dictionary(hybrid(2,0),heuristic(use_first(halving,delta_largest))))": 756,
"opt(dictionary(hybrid(2,16),continued_fractions(binary)))": 413,
"opt(dictionary(hybrid(2,16),continued_fractions(co_binary)))": 413,
"opt(dictionary(hybrid(2,16),continued_fractions(dichotomic)))": 413,
"opt(dictionary(hybrid(2,16),heuristic(use_first(halving,approximation))))": 413,
"opt(dictionary(hybrid(2,16),heuristic(use_first(halving,delta_largest))))": 415,
"opt(dictionary(hybrid(2,32),continued_fractions(binary)))": 402,
"opt(dictionary(hybrid(2,32),continued_fractions(co_binary)))": 402,
"opt(dictionary(hybrid(2,32),continued_fractions(dichotomic)))": 402,
"opt(dictionary(hybrid(2,32),heuristic(use_first(halving,approximation))))": 402,
"opt(dictionary(hybrid(2,32),heuristic(use_first(halving,delta_largest))))": 407,
"opt(dictionary(hybrid(2,64),continued_fractions(binary)))": 401,
"opt(dictionary(hybrid(2,64),continued_fractions(co_binary)))": 401,
"opt(dictionary(hybrid(2,64),continued_fractions(dichotomic)))": 398,
"opt(dictionary(hybrid(2,64),heuristic(use_first(halving,approximation))))": 401,
"opt(dictionary(hybrid(2,64),heuristic(use_first(halving,delta_largest))))": 432,
"opt(dictionary(hybrid(3,0),continued_fractions(binary)))": 572,
"opt(dictionary(hybrid(3,0),continued_fractions(co_binary)))": 572,
"opt(dictionary(hybrid(3,0),continued_fractions(dichotomic)))": 398,
"opt(dictionary(hybrid(3,0),heuristic(use_first(halving,approximation))))": 572,
"opt(dictionary(hybrid(3,0),heuristic(use_first(halving,delta_largest))))": 756,
"opt(dictionary(hybrid(3,16),continued_fractions(binary)))": 413,
"opt(dictionary(hybrid(3,16),continued_fractions(co_binary)))": 413,
"opt(dictionary(hybrid(3,16),continued_fractions(dichotomic)))": 413,
"opt(dictionary(hybrid(3,16),heuristic(use_first(halving,approximation))))": 413,
"opt(dictionary(hybrid(3,16),heuristic(use_first(halving,delta_largest))))": 415,
"opt(dictionary(hybrid(3,32),continued_fractions(binary)))": 402,
"opt(dictionary(hybrid(3,32),continued_fractions(co_binary)))": 402,
"opt(dictionary(hybrid(3,32),continued_fractions(dichotomic)))": 402,
"opt(dictionary(hybrid(3,32),heuristic(use_first(halving,approximation))))": 402,
"opt(dictionary(hybrid(3,32),heuristic(use_first(halving,delta_largest))))": 407,
"opt(dictionary(hybrid(3,64),continued_fractions(binary)))": 401,
"opt(dictionary(hybrid(3,64),continued_fractions(co_binary)))": 401,
"opt(dictionary(hybrid(3,64),continued_fractions(dichotomic)))": 398,
"opt(dictionary(hybrid(3,64),heuristic(use_first(halving,approximation))))": 401,
"opt(dictionary(hybrid(3,64),heuristic(use_first(halving,delta_largest))))": 432,
"opt(dictionary(hybrid(4,0),continued_fractions(binary)))": 572,
"opt(dictionary(hybrid(4,0),continued_fractions(co_binary)))": 572,
"opt(dictionary(hybrid(4,0),continued_fractions(dichotomic)))": 398,
"opt(dictionary(hybrid(4,0),heuristic(use_first(halving,approximation))))": 572,
"opt(dictionary(hybrid(4,0),heuristic(use_first(halving,delta_largest))))": 756,
"opt(dictionary(hybrid(4,16),continued_fractions(binary)))": 413,
"opt(dictionary(hybrid(4,16),continued_fractions(co_binary)))": 413,
"opt(dictionary(hybrid(4,16),continued_fractions(dichotomic)))": 413,
"opt(dictionary(hybrid(4,16),heuristic(use_first(halving,approximation))))": 413,
"opt(dictionary(hybrid(4,16),heuristic(use_first(halving,delta_largest))))": 415,
"opt(dictionary(hybrid(4,32),continued_fractions(binary)))": 402,
"opt(dictionary(hybrid(4,32),continued_fractions(co_binary)))": 402,
"opt(dictionary(hybrid(4,32),continued_fractions(dichotomic)))": 402,
"opt(dictionary(hybrid(4,32),heuristic(use_first(halving,approximation))))": 402,
"opt(dictionary(hybrid(4,32),heuristic(use_first(halving,delta_largest))))": 407,
"opt(dictionary(hybrid(4,64),continued_fractions(binary)))": 401,
"opt(dictionary(hybrid(4,64),continued_fractions(co_binary)))": 401,
"opt(dictionary(hybrid(4,64),continued_fractions(dichotomic)))": 398,
"opt(dictionary(hybrid(4,64),heuristic(use_first(halving,approximation))))": 401,
"opt(dictionary(hybrid(4,64),heuristic(use_first(halving,delta_largest))))": 432,
"opt(dictionary(hybrid(5,0),continued_fractions(binary)))": 572,
"opt(dictionary(hybrid(5,0),continued_fractions(co_binary)))": 572,
"opt(dictionary(hybrid(5,0),continued_fractions(dichotomic)))": 398,
"opt(dictionary(hybrid(5,0),heuristic(use_first(halving,approximation))))": 572,
"opt(dictionary(hybrid(5,0),heuristic(use_first(halving,delta_largest))))": 756,
"opt(dictionary(hybrid(5,16),continued_fractions(binary)))": 413,
"opt(dictionary(hybrid(5,16),continued_fractions(co_binary)))": 413,
"opt(dictionary(hybrid(5,16),continued_fractions(dichotomic)))": 413,
"opt(dictionary(hybrid(5,16),heuristic(use_first(halving,approximation))))": 413,
"opt(dictionary(hybrid(5,16),heuristic(use_first(halving,delta_largest))))": 415,
"opt(dictionary(hybrid(5,32),continued_fractions(binary)))": 402,
"opt(dictionary(hybrid(5,32),continued_fractions(co_binary)))": 402,
"opt(dictionary(hybrid(5,32),continued_fractions(dichotomic)))": 402,
"opt(dictionary(hybrid(5,32),heuristic(use_first(halving,approximation))))": 402,
"opt(dictionary(hybrid(5,32),heuristic(use_first(halving,delta_largest))))": 407,
"opt(dictionary(hybrid(5,64),continued_fractions(binary)))": 401,
"opt(dictionary(hybrid(5,64),continued_fractions(co_binary)))": 401,
"opt(dictionary(hybrid(5,64),continued_fractions(dichotomic)))": 398,
"opt(dictionary(hybrid(5,64),heuristic(use_first(halving,approximation))))": 401,
"opt(dictionary(hybrid(5,64),heuristic(use_first(halving,delta_largest))))": 432,
"opt(dictionary(hybrid(6,0),continued_fractions(binary)))": 573,
"opt(dictionary(hybrid(6,0),continued_fractions(co_binary)))": 573,
"opt(dictionary(hybrid(6,0),continued_fractions(dichotomic)))": 398,
"opt(dictionary(hybrid(6,0),heuristic(use_first(halving,approximation))))": 450,
"opt(dictionary(hybrid(6,0),heuristic(use_first(halving,delta_largest))))": 754,
"opt(dictionary(hybrid(6,16),continued_fractions(binary)))": 414,
"opt(dictionary(hybrid(6,16),continued_fractions(co_binary)))": 414,
"opt(dictionary(hybrid(6,16),continued_fractions(dichotomic)))": 414,
"opt(dictionary(hybrid(6,16),heuristic(use_first(halving,approximation))))": 413,
"opt(dictionary(hybrid(6,16),heuristic(use_first(halving,delta_largest))))": 415,
"opt(dictionary(hybrid(6,32),continued_fractions(binary)))": 406,
"opt(dictionary(hybrid(6,32),continued_fractions(co_binary)))": 406,
"opt(dictionary(hybrid(6,32),continued_fractions(dichotomic)))": 405,
"opt(dictionary(hybrid(6,32),heuristic(use_first(halving,approximation))))": 404,
"opt(dictionary(hybrid(6,32),heuristic(use_first(halving,delta_largest))))": 408,
"opt(dictionary(hybrid(6,64),continued_fractions(binary)))": 401,
"opt(dictionary(hybrid(6,64),continued_fractions(co_binary)))": 401,
"opt(dictionary(hybrid(6,64),continued_fractions(dichotomic)))": 398,
"opt(dictionary(hybrid(6,64),heuristic(use_first(halving,approximation))))": 401,
"opt(dictionary(hybrid(6,64),heuristic(use_first(halving,delta_largest))))": 433,
"opt(dictionary(hybrid(7,0),continued_fractions(binary)))": 572,
"opt(dictionary(hybrid(7,0),continued_fractions(co_binary)))": 572,
"opt(dictionary(hybrid(7,0),continued_fractions(dichotomic)))": 433,
"opt(dictionary(hybrid(7,0),heuristic(use_first(halving,approximation))))": 440,
"opt(dictionary(hybrid(7,0),heuristic(use_first(halving,delta_largest))))": 751,
"opt(dictionary(hybrid(7,16),continued_fractions(binary)))": 412,
"opt(dictionary(hybrid(7,16),continued_fractions(co_binary)))": 412,
"opt(dictionary(hybrid(7,16),continued_fractions(dichotomic)))": 412,
"opt(dictionary(hybrid(7,16),heuristic(use_first(halving,approximation))))": 412,
"opt(dictionary(hybrid(7,16),heuristic(use_first(halving,delta_largest))))": 415,
"opt(dictionary(hybrid(7,32),continued_fractions(binary)))": 404,
"opt(dictionary(hybrid(7,32),continued_fractions(co_binary)))": 404,
"opt(dictionary(hybrid(7,32),continued_fractions(dichotomic)))": 404,
"opt(dictionary(hybrid(7,32),heuristic(use_first(halving,approximation))))": 403,
"opt(dictionary(hybrid(7,32),heuristic(use_first(halving,delta_largest))))": 407,
"opt(dictionary(hybrid(7,64),continued_fractions(binary)))": 400,
"opt(dictionary(hybrid(7,64),continued_fractions(co_binary)))": 400,
"opt(dictionary(hybrid(7,64),continued_fractions(dichotomic)))": 398,
"opt(dictionary(hybrid(7,64),heuristic(use_first(halving,approximation))))": 400,
"opt(dictionary(hybrid(7,64),heuristic(use_first(halving,delta_largest))))": 432,
"opt(dictionary(hybrid(8,0),continued_fractions(binary)))": 572,
"opt(dictionary(hybrid(8,0),continued_fractions(co_binary)))": 572,
"opt(dictionary(hybrid(8,0),continued_fractions(dichotomic)))": 433,
"opt(dictionary(hybrid(8,0),heuristic(use_first(halving,approximation))))": 440,
"opt(dictionary(hybrid(8,0),heuristic(use_first(halving,delta_largest))))": 751,
"opt(dictionary(hybrid(8,16),continued_fractions(binary)))": 412,
"opt(dictionary(hybrid(8,16),continued_fractions(co_binary)))": 412,
"opt(dictionary(hybrid(8,16),continued_fractions(dichotomic)))": 412,
"opt(dictionary(hybrid(8,16),heuristic(use_first(halving,approximation))))": 412,
"opt(dictionary(hybrid(8,16),heuristic(use_first(halving,delta_largest))))": 415,
"opt(dictionary(hybrid(8,32),continued_fractions(binary)))": 404,
"opt(dictionary(hybrid(8,32),continued_fractions(co_binary)))": 404,
"opt(dictionary(hybrid(8,32),continued_fractions(dichotomic)))": 404,
"opt(dictionary(hybrid(8,32),heuristic(use_first(halving,approximation))))": 403,
"opt(dictionary(hybrid(8,32),heuristic(use_first(halving,delta_largest))))": 407,
"opt(dictionary(hybrid(8,64),continued_fractions(binary)))": 400,
"opt(dictionary(hybrid(8,64),continued_fractions(co_binary)))": 400,
"opt(dictionary(hybrid(8,64),continued_fractions(dichotomic)))": 398,
"opt(dictionary(hybrid(8,64),heuristic(use_first(halving,approximation))))": 400,
"opt(dictionary(hybrid(8,64),heuristic(use_first(halving,delta_largest))))": 432,
"opt(dictionary(run_length(0),continued_fractions(binary)))": 572,
"opt(dictionary(run_length(0),continued_fractions(co_binary)))": 572,
"opt(dictionary(run_length(0),continued_fractions(dichotomic)))": 398,
"opt(dictionary(run_length(0),heuristic(use_first(halving,approximation))))": 572,
"opt(dictionary(run_length(0),heuristic(use_first(halving,delta_largest))))": 756,
"opt(dictionary(run_length(128),continued_fractions(binary)))": 405,
"opt(dictionary(run_length(128),continued_fractions(co_binary)))": 405,
"opt(dictionary(run_length(128),continued_fractions(dichotomic)))": 397,
"opt(dictionary(run_length(128),heuristic(use_first(halving,approximation))))": 405,
"opt(dictionary(run_length(128),heuristic(use_first(halving,delta_largest))))": 494,
"opt(dictionary(run_length(16),continued_fractions(binary)))": 413,
"opt(dictionary(run_length(16),continued_fractions(co_binary)))": 413,
"opt(dictionary(run_length(16),continued_fractions(dichotomic)))": 413,
"opt(dictionary(run_length(16),heuristic(use_first(halving,approximation))))": 413,
"opt(dictionary(run_length(16),heuristic(use_first(halving,delta_largest))))": 415,
"opt(dictionary(run_length(32),continued_fractions(binary)))": 402,
"opt(dictionary(run_length(32),continued_fractions(co_binary)))": 402,
"opt(dictionary(run_length(32),continued_fractions(dichotomic)))": 402,
"opt(dictionary(run_length(32),heuristic(use_first(halving,approximation))))": 402,
"opt(dictionary(run_length(32),heuristic(use_first(halving,delta_largest))))": 407,
"opt(dictionary(run_length(64),continued_fractions(binary)))": 401,
"opt(dictionary(run_length(64),continued_fractions(co_binary)))": 401,
"opt(dictionary(run_length(64),continued_fractions(dichotomic)))": 398,
"opt(dictionary(run_length(64),heuristic(use_first(halving,approximation))))": 401,
"opt(dictionary(run_length(64),heuristic(use_first(halving,delta_largest))))": 432,
"opt(dictionary(sliding_window(128),continued_fractions(binary)))": 451,
"opt(dictionary(sliding_window(128),continued_fractions(co_binary)))": 451,
"opt(dictionary(sliding_window(128),continued_fractions(dichotomic)))": 411,
"opt(dictionary(sliding_window(128),heuristic(use_first(halving,approximation))))": 413,
"opt(dictionary(sliding_window(128),heuristic(use_first(halving,delta_largest))))": 504,
"opt(dictionary(sliding_window(16),continued_fractions(binary)))": 416,
"opt(dictionary(sliding_window(16),continued_fractions(co_binary)))": 416,
"opt(dictionary(sliding_window(16),continued_fractions(dichotomic)))": 414,
"opt(dictionary(sliding_window(16),heuristic(use_first(halving,approximation))))": 413,
"opt(dictionary(sliding_window(16),heuristic(use_first(halving,delta_largest))))": 413,
"opt(dictionary(sliding_window(32),continued_fractions(binary)))": 412,
"opt(dictionary(sliding_window(32),continued_fractions(co_binary)))": 412,
"opt(dictionary(sliding_window(32),continued_fractions(dichotomic)))": 407,
"opt(dictionary(sliding_window(32),heuristic(use_first(halving,approximation))))": 410,
"opt(dictionary(sliding_window(32),heuristic(use_first(halving,delta_largest))))": 417,
"opt(dictionary(sliding_window(4),continued_fractions(binary)))": 480,
"opt(dictionary(sliding_window(4),continued_fractions(co_binary)))": 480,
"opt(dictionary(sliding_window(4),continued_fractions(dichotomic)))": 480,
"opt(dictionary(sliding_window(4),heuristic(use_first(halving,approximation))))": 480,
"opt(dictionary(sliding_window(4),heuristic(use_first(halving,delta_largest))))": 480,
"opt(dictionary(sliding_window(64),continued_fractions(binary)))": 424,
"opt(dictionary(sliding_window(64),continued_fractions(co_binary)))": 424,
"opt(dictionary(sliding_window(64),continued_fractions(dichotomic)))": 411,
"opt(dictionary(sliding_window(64),heuristic(use_first(halving,approximation))))": 408,
"opt(dictionary(sliding_window(64),heuristic(use_first(halving,delta_largest))))": 443,
"opt(dictionary(sliding_window(8),continued_fractions(binary)))": 434,
"opt(dictionary(sliding_window(8),continued_fractions(co_binary)))": 434,
"opt(dictionary(sliding_window(8),continued_fractions(dichotomic)))": 434,
"opt(dictionary(sliding_window(8),heuristic(use_first(halving,approximation))))": 434,
"opt(dictionary(sliding_window(8),heuristic(use_first(halving,delta_largest))))": 434,
"opt(runs(continued_fractions(binary)))": 398,
"opt(runs(continued_fractions(co_binary)))": 398,
"opt(runs(continued_fractions(dichotomic)))": 396,
"opt(runs(heuristic(use_first(halving,approximation))))": 398,
"opt(runs(heuristic(use_first(halving,delta_largest))))": 399
} addchain-0.4.0/alg/ensemble/testdata/p384_field.golden 0000664 0000000 0000000 00000035321 15143052566 0022462 0 ustar 00root root 0000000 0000000 {
"opt(dictionary(hybrid(2,0),continued_fractions(binary)))": 423,
"opt(dictionary(hybrid(2,0),continued_fractions(co_binary)))": 423,
"opt(dictionary(hybrid(2,0),continued_fractions(dichotomic)))": 399,
"opt(dictionary(hybrid(2,0),heuristic(use_first(halving,approximation))))": 409,
"opt(dictionary(hybrid(2,0),heuristic(use_first(halving,delta_largest))))": 605,
"opt(dictionary(hybrid(2,16),continued_fractions(binary)))": 417,
"opt(dictionary(hybrid(2,16),continued_fractions(co_binary)))": 417,
"opt(dictionary(hybrid(2,16),continued_fractions(dichotomic)))": 409,
"opt(dictionary(hybrid(2,16),heuristic(use_first(halving,approximation))))": 411,
"opt(dictionary(hybrid(2,16),heuristic(use_first(halving,delta_largest))))": 414,
"opt(dictionary(hybrid(2,32),continued_fractions(binary)))": 423,
"opt(dictionary(hybrid(2,32),continued_fractions(co_binary)))": 423,
"opt(dictionary(hybrid(2,32),continued_fractions(dichotomic)))": 401,
"opt(dictionary(hybrid(2,32),heuristic(use_first(halving,approximation))))": 409,
"opt(dictionary(hybrid(2,32),heuristic(use_first(halving,delta_largest))))": 420,
"opt(dictionary(hybrid(2,64),continued_fractions(binary)))": 421,
"opt(dictionary(hybrid(2,64),continued_fractions(co_binary)))": 421,
"opt(dictionary(hybrid(2,64),continued_fractions(dichotomic)))": 399,
"opt(dictionary(hybrid(2,64),heuristic(use_first(halving,approximation))))": 407,
"opt(dictionary(hybrid(2,64),heuristic(use_first(halving,delta_largest))))": 418,
"opt(dictionary(hybrid(3,0),continued_fractions(binary)))": 423,
"opt(dictionary(hybrid(3,0),continued_fractions(co_binary)))": 423,
"opt(dictionary(hybrid(3,0),continued_fractions(dichotomic)))": 399,
"opt(dictionary(hybrid(3,0),heuristic(use_first(halving,approximation))))": 409,
"opt(dictionary(hybrid(3,0),heuristic(use_first(halving,delta_largest))))": 605,
"opt(dictionary(hybrid(3,16),continued_fractions(binary)))": 417,
"opt(dictionary(hybrid(3,16),continued_fractions(co_binary)))": 417,
"opt(dictionary(hybrid(3,16),continued_fractions(dichotomic)))": 409,
"opt(dictionary(hybrid(3,16),heuristic(use_first(halving,approximation))))": 411,
"opt(dictionary(hybrid(3,16),heuristic(use_first(halving,delta_largest))))": 414,
"opt(dictionary(hybrid(3,32),continued_fractions(binary)))": 423,
"opt(dictionary(hybrid(3,32),continued_fractions(co_binary)))": 423,
"opt(dictionary(hybrid(3,32),continued_fractions(dichotomic)))": 401,
"opt(dictionary(hybrid(3,32),heuristic(use_first(halving,approximation))))": 409,
"opt(dictionary(hybrid(3,32),heuristic(use_first(halving,delta_largest))))": 420,
"opt(dictionary(hybrid(3,64),continued_fractions(binary)))": 421,
"opt(dictionary(hybrid(3,64),continued_fractions(co_binary)))": 421,
"opt(dictionary(hybrid(3,64),continued_fractions(dichotomic)))": 399,
"opt(dictionary(hybrid(3,64),heuristic(use_first(halving,approximation))))": 407,
"opt(dictionary(hybrid(3,64),heuristic(use_first(halving,delta_largest))))": 418,
"opt(dictionary(hybrid(4,0),continued_fractions(binary)))": 423,
"opt(dictionary(hybrid(4,0),continued_fractions(co_binary)))": 423,
"opt(dictionary(hybrid(4,0),continued_fractions(dichotomic)))": 399,
"opt(dictionary(hybrid(4,0),heuristic(use_first(halving,approximation))))": 409,
"opt(dictionary(hybrid(4,0),heuristic(use_first(halving,delta_largest))))": 605,
"opt(dictionary(hybrid(4,16),continued_fractions(binary)))": 417,
"opt(dictionary(hybrid(4,16),continued_fractions(co_binary)))": 417,
"opt(dictionary(hybrid(4,16),continued_fractions(dichotomic)))": 409,
"opt(dictionary(hybrid(4,16),heuristic(use_first(halving,approximation))))": 411,
"opt(dictionary(hybrid(4,16),heuristic(use_first(halving,delta_largest))))": 414,
"opt(dictionary(hybrid(4,32),continued_fractions(binary)))": 423,
"opt(dictionary(hybrid(4,32),continued_fractions(co_binary)))": 423,
"opt(dictionary(hybrid(4,32),continued_fractions(dichotomic)))": 401,
"opt(dictionary(hybrid(4,32),heuristic(use_first(halving,approximation))))": 409,
"opt(dictionary(hybrid(4,32),heuristic(use_first(halving,delta_largest))))": 420,
"opt(dictionary(hybrid(4,64),continued_fractions(binary)))": 421,
"opt(dictionary(hybrid(4,64),continued_fractions(co_binary)))": 421,
"opt(dictionary(hybrid(4,64),continued_fractions(dichotomic)))": 399,
"opt(dictionary(hybrid(4,64),heuristic(use_first(halving,approximation))))": 407,
"opt(dictionary(hybrid(4,64),heuristic(use_first(halving,delta_largest))))": 418,
"opt(dictionary(hybrid(5,0),continued_fractions(binary)))": 423,
"opt(dictionary(hybrid(5,0),continued_fractions(co_binary)))": 423,
"opt(dictionary(hybrid(5,0),continued_fractions(dichotomic)))": 399,
"opt(dictionary(hybrid(5,0),heuristic(use_first(halving,approximation))))": 409,
"opt(dictionary(hybrid(5,0),heuristic(use_first(halving,delta_largest))))": 605,
"opt(dictionary(hybrid(5,16),continued_fractions(binary)))": 417,
"opt(dictionary(hybrid(5,16),continued_fractions(co_binary)))": 417,
"opt(dictionary(hybrid(5,16),continued_fractions(dichotomic)))": 409,
"opt(dictionary(hybrid(5,16),heuristic(use_first(halving,approximation))))": 411,
"opt(dictionary(hybrid(5,16),heuristic(use_first(halving,delta_largest))))": 414,
"opt(dictionary(hybrid(5,32),continued_fractions(binary)))": 423,
"opt(dictionary(hybrid(5,32),continued_fractions(co_binary)))": 423,
"opt(dictionary(hybrid(5,32),continued_fractions(dichotomic)))": 401,
"opt(dictionary(hybrid(5,32),heuristic(use_first(halving,approximation))))": 409,
"opt(dictionary(hybrid(5,32),heuristic(use_first(halving,delta_largest))))": 420,
"opt(dictionary(hybrid(5,64),continued_fractions(binary)))": 421,
"opt(dictionary(hybrid(5,64),continued_fractions(co_binary)))": 421,
"opt(dictionary(hybrid(5,64),continued_fractions(dichotomic)))": 399,
"opt(dictionary(hybrid(5,64),heuristic(use_first(halving,approximation))))": 407,
"opt(dictionary(hybrid(5,64),heuristic(use_first(halving,delta_largest))))": 418,
"opt(dictionary(hybrid(6,0),continued_fractions(binary)))": 423,
"opt(dictionary(hybrid(6,0),continued_fractions(co_binary)))": 423,
"opt(dictionary(hybrid(6,0),continued_fractions(dichotomic)))": 399,
"opt(dictionary(hybrid(6,0),heuristic(use_first(halving,approximation))))": 409,
"opt(dictionary(hybrid(6,0),heuristic(use_first(halving,delta_largest))))": 605,
"opt(dictionary(hybrid(6,16),continued_fractions(binary)))": 417,
"opt(dictionary(hybrid(6,16),continued_fractions(co_binary)))": 417,
"opt(dictionary(hybrid(6,16),continued_fractions(dichotomic)))": 409,
"opt(dictionary(hybrid(6,16),heuristic(use_first(halving,approximation))))": 411,
"opt(dictionary(hybrid(6,16),heuristic(use_first(halving,delta_largest))))": 414,
"opt(dictionary(hybrid(6,32),continued_fractions(binary)))": 423,
"opt(dictionary(hybrid(6,32),continued_fractions(co_binary)))": 423,
"opt(dictionary(hybrid(6,32),continued_fractions(dichotomic)))": 401,
"opt(dictionary(hybrid(6,32),heuristic(use_first(halving,approximation))))": 409,
"opt(dictionary(hybrid(6,32),heuristic(use_first(halving,delta_largest))))": 420,
"opt(dictionary(hybrid(6,64),continued_fractions(binary)))": 421,
"opt(dictionary(hybrid(6,64),continued_fractions(co_binary)))": 421,
"opt(dictionary(hybrid(6,64),continued_fractions(dichotomic)))": 399,
"opt(dictionary(hybrid(6,64),heuristic(use_first(halving,approximation))))": 407,
"opt(dictionary(hybrid(6,64),heuristic(use_first(halving,delta_largest))))": 418,
"opt(dictionary(hybrid(7,0),continued_fractions(binary)))": 423,
"opt(dictionary(hybrid(7,0),continued_fractions(co_binary)))": 423,
"opt(dictionary(hybrid(7,0),continued_fractions(dichotomic)))": 399,
"opt(dictionary(hybrid(7,0),heuristic(use_first(halving,approximation))))": 409,
"opt(dictionary(hybrid(7,0),heuristic(use_first(halving,delta_largest))))": 605,
"opt(dictionary(hybrid(7,16),continued_fractions(binary)))": 417,
"opt(dictionary(hybrid(7,16),continued_fractions(co_binary)))": 417,
"opt(dictionary(hybrid(7,16),continued_fractions(dichotomic)))": 409,
"opt(dictionary(hybrid(7,16),heuristic(use_first(halving,approximation))))": 411,
"opt(dictionary(hybrid(7,16),heuristic(use_first(halving,delta_largest))))": 414,
"opt(dictionary(hybrid(7,32),continued_fractions(binary)))": 423,
"opt(dictionary(hybrid(7,32),continued_fractions(co_binary)))": 423,
"opt(dictionary(hybrid(7,32),continued_fractions(dichotomic)))": 401,
"opt(dictionary(hybrid(7,32),heuristic(use_first(halving,approximation))))": 409,
"opt(dictionary(hybrid(7,32),heuristic(use_first(halving,delta_largest))))": 420,
"opt(dictionary(hybrid(7,64),continued_fractions(binary)))": 421,
"opt(dictionary(hybrid(7,64),continued_fractions(co_binary)))": 421,
"opt(dictionary(hybrid(7,64),continued_fractions(dichotomic)))": 399,
"opt(dictionary(hybrid(7,64),heuristic(use_first(halving,approximation))))": 407,
"opt(dictionary(hybrid(7,64),heuristic(use_first(halving,delta_largest))))": 418,
"opt(dictionary(hybrid(8,0),continued_fractions(binary)))": 423,
"opt(dictionary(hybrid(8,0),continued_fractions(co_binary)))": 423,
"opt(dictionary(hybrid(8,0),continued_fractions(dichotomic)))": 399,
"opt(dictionary(hybrid(8,0),heuristic(use_first(halving,approximation))))": 409,
"opt(dictionary(hybrid(8,0),heuristic(use_first(halving,delta_largest))))": 605,
"opt(dictionary(hybrid(8,16),continued_fractions(binary)))": 417,
"opt(dictionary(hybrid(8,16),continued_fractions(co_binary)))": 417,
"opt(dictionary(hybrid(8,16),continued_fractions(dichotomic)))": 409,
"opt(dictionary(hybrid(8,16),heuristic(use_first(halving,approximation))))": 411,
"opt(dictionary(hybrid(8,16),heuristic(use_first(halving,delta_largest))))": 414,
"opt(dictionary(hybrid(8,32),continued_fractions(binary)))": 423,
"opt(dictionary(hybrid(8,32),continued_fractions(co_binary)))": 423,
"opt(dictionary(hybrid(8,32),continued_fractions(dichotomic)))": 401,
"opt(dictionary(hybrid(8,32),heuristic(use_first(halving,approximation))))": 409,
"opt(dictionary(hybrid(8,32),heuristic(use_first(halving,delta_largest))))": 420,
"opt(dictionary(hybrid(8,64),continued_fractions(binary)))": 421,
"opt(dictionary(hybrid(8,64),continued_fractions(co_binary)))": 421,
"opt(dictionary(hybrid(8,64),continued_fractions(dichotomic)))": 399,
"opt(dictionary(hybrid(8,64),heuristic(use_first(halving,approximation))))": 407,
"opt(dictionary(hybrid(8,64),heuristic(use_first(halving,delta_largest))))": 418,
"opt(dictionary(run_length(0),continued_fractions(binary)))": 423,
"opt(dictionary(run_length(0),continued_fractions(co_binary)))": 423,
"opt(dictionary(run_length(0),continued_fractions(dichotomic)))": 399,
"opt(dictionary(run_length(0),heuristic(use_first(halving,approximation))))": 409,
"opt(dictionary(run_length(0),heuristic(use_first(halving,delta_largest))))": 605,
"opt(dictionary(run_length(128),continued_fractions(binary)))": 421,
"opt(dictionary(run_length(128),continued_fractions(co_binary)))": 421,
"opt(dictionary(run_length(128),continued_fractions(dichotomic)))": 399,
"opt(dictionary(run_length(128),heuristic(use_first(halving,approximation))))": 407,
"opt(dictionary(run_length(128),heuristic(use_first(halving,delta_largest))))": 479,
"opt(dictionary(run_length(16),continued_fractions(binary)))": 417,
"opt(dictionary(run_length(16),continued_fractions(co_binary)))": 417,
"opt(dictionary(run_length(16),continued_fractions(dichotomic)))": 409,
"opt(dictionary(run_length(16),heuristic(use_first(halving,approximation))))": 411,
"opt(dictionary(run_length(16),heuristic(use_first(halving,delta_largest))))": 414,
"opt(dictionary(run_length(32),continued_fractions(binary)))": 423,
"opt(dictionary(run_length(32),continued_fractions(co_binary)))": 423,
"opt(dictionary(run_length(32),continued_fractions(dichotomic)))": 401,
"opt(dictionary(run_length(32),heuristic(use_first(halving,approximation))))": 409,
"opt(dictionary(run_length(32),heuristic(use_first(halving,delta_largest))))": 420,
"opt(dictionary(run_length(64),continued_fractions(binary)))": 421,
"opt(dictionary(run_length(64),continued_fractions(co_binary)))": 421,
"opt(dictionary(run_length(64),continued_fractions(dichotomic)))": 399,
"opt(dictionary(run_length(64),heuristic(use_first(halving,approximation))))": 407,
"opt(dictionary(run_length(64),heuristic(use_first(halving,delta_largest))))": 418,
"opt(dictionary(sliding_window(128),continued_fractions(binary)))": 451,
"opt(dictionary(sliding_window(128),continued_fractions(co_binary)))": 451,
"opt(dictionary(sliding_window(128),continued_fractions(dichotomic)))": 419,
"opt(dictionary(sliding_window(128),heuristic(use_first(halving,approximation))))": 406,
"opt(dictionary(sliding_window(128),heuristic(use_first(halving,delta_largest))))": 421,
"opt(dictionary(sliding_window(16),continued_fractions(binary)))": 417,
"opt(dictionary(sliding_window(16),continued_fractions(co_binary)))": 417,
"opt(dictionary(sliding_window(16),continued_fractions(dichotomic)))": 409,
"opt(dictionary(sliding_window(16),heuristic(use_first(halving,approximation))))": 411,
"opt(dictionary(sliding_window(16),heuristic(use_first(halving,delta_largest))))": 414,
"opt(dictionary(sliding_window(32),continued_fractions(binary)))": 423,
"opt(dictionary(sliding_window(32),continued_fractions(co_binary)))": 423,
"opt(dictionary(sliding_window(32),continued_fractions(dichotomic)))": 401,
"opt(dictionary(sliding_window(32),heuristic(use_first(halving,approximation))))": 409,
"opt(dictionary(sliding_window(32),heuristic(use_first(halving,delta_largest))))": 420,
"opt(dictionary(sliding_window(4),continued_fractions(binary)))": 465,
"opt(dictionary(sliding_window(4),continued_fractions(co_binary)))": 465,
"opt(dictionary(sliding_window(4),continued_fractions(dichotomic)))": 465,
"opt(dictionary(sliding_window(4),heuristic(use_first(halving,approximation))))": 465,
"opt(dictionary(sliding_window(4),heuristic(use_first(halving,delta_largest))))": 465,
"opt(dictionary(sliding_window(64),continued_fractions(binary)))": 421,
"opt(dictionary(sliding_window(64),continued_fractions(co_binary)))": 421,
"opt(dictionary(sliding_window(64),continued_fractions(dichotomic)))": 399,
"opt(dictionary(sliding_window(64),heuristic(use_first(halving,approximation))))": 407,
"opt(dictionary(sliding_window(64),heuristic(use_first(halving,delta_largest))))": 418,
"opt(dictionary(sliding_window(8),continued_fractions(binary)))": 429,
"opt(dictionary(sliding_window(8),continued_fractions(co_binary)))": 429,
"opt(dictionary(sliding_window(8),continued_fractions(dichotomic)))": 427,
"opt(dictionary(sliding_window(8),heuristic(use_first(halving,approximation))))": 427,
"opt(dictionary(sliding_window(8),heuristic(use_first(halving,delta_largest))))": 427,
"opt(runs(continued_fractions(binary)))": 399,
"opt(runs(continued_fractions(co_binary)))": 399,
"opt(runs(continued_fractions(dichotomic)))": 399,
"opt(runs(heuristic(use_first(halving,approximation))))": 397,
"opt(runs(heuristic(use_first(halving,delta_largest))))": 397
} addchain-0.4.0/alg/ensemble/testdata/p384_scalar.golden 0000664 0000000 0000000 00000035321 15143052566 0022644 0 ustar 00root root 0000000 0000000 {
"opt(dictionary(hybrid(2,0),continued_fractions(binary)))": 475,
"opt(dictionary(hybrid(2,0),continued_fractions(co_binary)))": 475,
"opt(dictionary(hybrid(2,0),continued_fractions(dichotomic)))": 445,
"opt(dictionary(hybrid(2,0),heuristic(use_first(halving,approximation))))": 475,
"opt(dictionary(hybrid(2,0),heuristic(use_first(halving,delta_largest))))": 622,
"opt(dictionary(hybrid(2,16),continued_fractions(binary)))": 452,
"opt(dictionary(hybrid(2,16),continued_fractions(co_binary)))": 452,
"opt(dictionary(hybrid(2,16),continued_fractions(dichotomic)))": 452,
"opt(dictionary(hybrid(2,16),heuristic(use_first(halving,approximation))))": 452,
"opt(dictionary(hybrid(2,16),heuristic(use_first(halving,delta_largest))))": 455,
"opt(dictionary(hybrid(2,32),continued_fractions(binary)))": 449,
"opt(dictionary(hybrid(2,32),continued_fractions(co_binary)))": 449,
"opt(dictionary(hybrid(2,32),continued_fractions(dichotomic)))": 447,
"opt(dictionary(hybrid(2,32),heuristic(use_first(halving,approximation))))": 449,
"opt(dictionary(hybrid(2,32),heuristic(use_first(halving,delta_largest))))": 465,
"opt(dictionary(hybrid(2,64),continued_fractions(binary)))": 452,
"opt(dictionary(hybrid(2,64),continued_fractions(co_binary)))": 452,
"opt(dictionary(hybrid(2,64),continued_fractions(dichotomic)))": 445,
"opt(dictionary(hybrid(2,64),heuristic(use_first(halving,approximation))))": 452,
"opt(dictionary(hybrid(2,64),heuristic(use_first(halving,delta_largest))))": 495,
"opt(dictionary(hybrid(3,0),continued_fractions(binary)))": 471,
"opt(dictionary(hybrid(3,0),continued_fractions(co_binary)))": 471,
"opt(dictionary(hybrid(3,0),continued_fractions(dichotomic)))": 441,
"opt(dictionary(hybrid(3,0),heuristic(use_first(halving,approximation))))": 471,
"opt(dictionary(hybrid(3,0),heuristic(use_first(halving,delta_largest))))": 618,
"opt(dictionary(hybrid(3,16),continued_fractions(binary)))": 448,
"opt(dictionary(hybrid(3,16),continued_fractions(co_binary)))": 448,
"opt(dictionary(hybrid(3,16),continued_fractions(dichotomic)))": 448,
"opt(dictionary(hybrid(3,16),heuristic(use_first(halving,approximation))))": 448,
"opt(dictionary(hybrid(3,16),heuristic(use_first(halving,delta_largest))))": 451,
"opt(dictionary(hybrid(3,32),continued_fractions(binary)))": 445,
"opt(dictionary(hybrid(3,32),continued_fractions(co_binary)))": 445,
"opt(dictionary(hybrid(3,32),continued_fractions(dichotomic)))": 443,
"opt(dictionary(hybrid(3,32),heuristic(use_first(halving,approximation))))": 445,
"opt(dictionary(hybrid(3,32),heuristic(use_first(halving,delta_largest))))": 462,
"opt(dictionary(hybrid(3,64),continued_fractions(binary)))": 448,
"opt(dictionary(hybrid(3,64),continued_fractions(co_binary)))": 448,
"opt(dictionary(hybrid(3,64),continued_fractions(dichotomic)))": 441,
"opt(dictionary(hybrid(3,64),heuristic(use_first(halving,approximation))))": 448,
"opt(dictionary(hybrid(3,64),heuristic(use_first(halving,delta_largest))))": 491,
"opt(dictionary(hybrid(4,0),continued_fractions(binary)))": 464,
"opt(dictionary(hybrid(4,0),continued_fractions(co_binary)))": 464,
"opt(dictionary(hybrid(4,0),continued_fractions(dichotomic)))": 434,
"opt(dictionary(hybrid(4,0),heuristic(use_first(halving,approximation))))": 464,
"opt(dictionary(hybrid(4,0),heuristic(use_first(halving,delta_largest))))": 611,
"opt(dictionary(hybrid(4,16),continued_fractions(binary)))": 441,
"opt(dictionary(hybrid(4,16),continued_fractions(co_binary)))": 441,
"opt(dictionary(hybrid(4,16),continued_fractions(dichotomic)))": 441,
"opt(dictionary(hybrid(4,16),heuristic(use_first(halving,approximation))))": 441,
"opt(dictionary(hybrid(4,16),heuristic(use_first(halving,delta_largest))))": 444,
"opt(dictionary(hybrid(4,32),continued_fractions(binary)))": 438,
"opt(dictionary(hybrid(4,32),continued_fractions(co_binary)))": 438,
"opt(dictionary(hybrid(4,32),continued_fractions(dichotomic)))": 436,
"opt(dictionary(hybrid(4,32),heuristic(use_first(halving,approximation))))": 438,
"opt(dictionary(hybrid(4,32),heuristic(use_first(halving,delta_largest))))": 455,
"opt(dictionary(hybrid(4,64),continued_fractions(binary)))": 441,
"opt(dictionary(hybrid(4,64),continued_fractions(co_binary)))": 441,
"opt(dictionary(hybrid(4,64),continued_fractions(dichotomic)))": 434,
"opt(dictionary(hybrid(4,64),heuristic(use_first(halving,approximation))))": 441,
"opt(dictionary(hybrid(4,64),heuristic(use_first(halving,delta_largest))))": 484,
"opt(dictionary(hybrid(5,0),continued_fractions(binary)))": 465,
"opt(dictionary(hybrid(5,0),continued_fractions(co_binary)))": 465,
"opt(dictionary(hybrid(5,0),continued_fractions(dichotomic)))": 435,
"opt(dictionary(hybrid(5,0),heuristic(use_first(halving,approximation))))": 465,
"opt(dictionary(hybrid(5,0),heuristic(use_first(halving,delta_largest))))": 612,
"opt(dictionary(hybrid(5,16),continued_fractions(binary)))": 441,
"opt(dictionary(hybrid(5,16),continued_fractions(co_binary)))": 441,
"opt(dictionary(hybrid(5,16),continued_fractions(dichotomic)))": 441,
"opt(dictionary(hybrid(5,16),heuristic(use_first(halving,approximation))))": 441,
"opt(dictionary(hybrid(5,16),heuristic(use_first(halving,delta_largest))))": 445,
"opt(dictionary(hybrid(5,32),continued_fractions(binary)))": 438,
"opt(dictionary(hybrid(5,32),continued_fractions(co_binary)))": 438,
"opt(dictionary(hybrid(5,32),continued_fractions(dichotomic)))": 436,
"opt(dictionary(hybrid(5,32),heuristic(use_first(halving,approximation))))": 438,
"opt(dictionary(hybrid(5,32),heuristic(use_first(halving,delta_largest))))": 456,
"opt(dictionary(hybrid(5,64),continued_fractions(binary)))": 442,
"opt(dictionary(hybrid(5,64),continued_fractions(co_binary)))": 442,
"opt(dictionary(hybrid(5,64),continued_fractions(dichotomic)))": 435,
"opt(dictionary(hybrid(5,64),heuristic(use_first(halving,approximation))))": 442,
"opt(dictionary(hybrid(5,64),heuristic(use_first(halving,delta_largest))))": 485,
"opt(dictionary(hybrid(6,0),continued_fractions(binary)))": 520,
"opt(dictionary(hybrid(6,0),continued_fractions(co_binary)))": 520,
"opt(dictionary(hybrid(6,0),continued_fractions(dichotomic)))": 454,
"opt(dictionary(hybrid(6,0),heuristic(use_first(halving,approximation))))": 460,
"opt(dictionary(hybrid(6,0),heuristic(use_first(halving,delta_largest))))": 612,
"opt(dictionary(hybrid(6,16),continued_fractions(binary)))": 443,
"opt(dictionary(hybrid(6,16),continued_fractions(co_binary)))": 443,
"opt(dictionary(hybrid(6,16),continued_fractions(dichotomic)))": 442,
"opt(dictionary(hybrid(6,16),heuristic(use_first(halving,approximation))))": 441,
"opt(dictionary(hybrid(6,16),heuristic(use_first(halving,delta_largest))))": 445,
"opt(dictionary(hybrid(6,32),continued_fractions(binary)))": 448,
"opt(dictionary(hybrid(6,32),continued_fractions(co_binary)))": 448,
"opt(dictionary(hybrid(6,32),continued_fractions(dichotomic)))": 442,
"opt(dictionary(hybrid(6,32),heuristic(use_first(halving,approximation))))": 439,
"opt(dictionary(hybrid(6,32),heuristic(use_first(halving,delta_largest))))": 456,
"opt(dictionary(hybrid(6,64),continued_fractions(binary)))": 459,
"opt(dictionary(hybrid(6,64),continued_fractions(co_binary)))": 459,
"opt(dictionary(hybrid(6,64),continued_fractions(dichotomic)))": 444,
"opt(dictionary(hybrid(6,64),heuristic(use_first(halving,approximation))))": 440,
"opt(dictionary(hybrid(6,64),heuristic(use_first(halving,delta_largest))))": 484,
"opt(dictionary(hybrid(7,0),continued_fractions(binary)))": 523,
"opt(dictionary(hybrid(7,0),continued_fractions(co_binary)))": 523,
"opt(dictionary(hybrid(7,0),continued_fractions(dichotomic)))": 451,
"opt(dictionary(hybrid(7,0),heuristic(use_first(halving,approximation))))": 458,
"opt(dictionary(hybrid(7,0),heuristic(use_first(halving,delta_largest))))": 611,
"opt(dictionary(hybrid(7,16),continued_fractions(binary)))": 443,
"opt(dictionary(hybrid(7,16),continued_fractions(co_binary)))": 443,
"opt(dictionary(hybrid(7,16),continued_fractions(dichotomic)))": 443,
"opt(dictionary(hybrid(7,16),heuristic(use_first(halving,approximation))))": 444,
"opt(dictionary(hybrid(7,16),heuristic(use_first(halving,delta_largest))))": 444,
"opt(dictionary(hybrid(7,32),continued_fractions(binary)))": 445,
"opt(dictionary(hybrid(7,32),continued_fractions(co_binary)))": 445,
"opt(dictionary(hybrid(7,32),continued_fractions(dichotomic)))": 442,
"opt(dictionary(hybrid(7,32),heuristic(use_first(halving,approximation))))": 441,
"opt(dictionary(hybrid(7,32),heuristic(use_first(halving,delta_largest))))": 455,
"opt(dictionary(hybrid(7,64),continued_fractions(binary)))": 462,
"opt(dictionary(hybrid(7,64),continued_fractions(co_binary)))": 462,
"opt(dictionary(hybrid(7,64),continued_fractions(dichotomic)))": 445,
"opt(dictionary(hybrid(7,64),heuristic(use_first(halving,approximation))))": 443,
"opt(dictionary(hybrid(7,64),heuristic(use_first(halving,delta_largest))))": 482,
"opt(dictionary(hybrid(8,0),continued_fractions(binary)))": 520,
"opt(dictionary(hybrid(8,0),continued_fractions(co_binary)))": 520,
"opt(dictionary(hybrid(8,0),continued_fractions(dichotomic)))": 458,
"opt(dictionary(hybrid(8,0),heuristic(use_first(halving,approximation))))": 451,
"opt(dictionary(hybrid(8,0),heuristic(use_first(halving,delta_largest))))": 607,
"opt(dictionary(hybrid(8,16),continued_fractions(binary)))": 443,
"opt(dictionary(hybrid(8,16),continued_fractions(co_binary)))": 443,
"opt(dictionary(hybrid(8,16),continued_fractions(dichotomic)))": 443,
"opt(dictionary(hybrid(8,16),heuristic(use_first(halving,approximation))))": 441,
"opt(dictionary(hybrid(8,16),heuristic(use_first(halving,delta_largest))))": 439,
"opt(dictionary(hybrid(8,32),continued_fractions(binary)))": 447,
"opt(dictionary(hybrid(8,32),continued_fractions(co_binary)))": 447,
"opt(dictionary(hybrid(8,32),continued_fractions(dichotomic)))": 441,
"opt(dictionary(hybrid(8,32),heuristic(use_first(halving,approximation))))": 437,
"opt(dictionary(hybrid(8,32),heuristic(use_first(halving,delta_largest))))": 447,
"opt(dictionary(hybrid(8,64),continued_fractions(binary)))": 460,
"opt(dictionary(hybrid(8,64),continued_fractions(co_binary)))": 460,
"opt(dictionary(hybrid(8,64),continued_fractions(dichotomic)))": 441,
"opt(dictionary(hybrid(8,64),heuristic(use_first(halving,approximation))))": 438,
"opt(dictionary(hybrid(8,64),heuristic(use_first(halving,delta_largest))))": 476,
"opt(dictionary(run_length(0),continued_fractions(binary)))": 475,
"opt(dictionary(run_length(0),continued_fractions(co_binary)))": 475,
"opt(dictionary(run_length(0),continued_fractions(dichotomic)))": 445,
"opt(dictionary(run_length(0),heuristic(use_first(halving,approximation))))": 475,
"opt(dictionary(run_length(0),heuristic(use_first(halving,delta_largest))))": 622,
"opt(dictionary(run_length(128),continued_fractions(binary)))": 452,
"opt(dictionary(run_length(128),continued_fractions(co_binary)))": 452,
"opt(dictionary(run_length(128),continued_fractions(dichotomic)))": 445,
"opt(dictionary(run_length(128),heuristic(use_first(halving,approximation))))": 452,
"opt(dictionary(run_length(128),heuristic(use_first(halving,delta_largest))))": 492,
"opt(dictionary(run_length(16),continued_fractions(binary)))": 452,
"opt(dictionary(run_length(16),continued_fractions(co_binary)))": 452,
"opt(dictionary(run_length(16),continued_fractions(dichotomic)))": 452,
"opt(dictionary(run_length(16),heuristic(use_first(halving,approximation))))": 452,
"opt(dictionary(run_length(16),heuristic(use_first(halving,delta_largest))))": 455,
"opt(dictionary(run_length(32),continued_fractions(binary)))": 449,
"opt(dictionary(run_length(32),continued_fractions(co_binary)))": 449,
"opt(dictionary(run_length(32),continued_fractions(dichotomic)))": 447,
"opt(dictionary(run_length(32),heuristic(use_first(halving,approximation))))": 449,
"opt(dictionary(run_length(32),heuristic(use_first(halving,delta_largest))))": 465,
"opt(dictionary(run_length(64),continued_fractions(binary)))": 452,
"opt(dictionary(run_length(64),continued_fractions(co_binary)))": 452,
"opt(dictionary(run_length(64),continued_fractions(dichotomic)))": 445,
"opt(dictionary(run_length(64),heuristic(use_first(halving,approximation))))": 452,
"opt(dictionary(run_length(64),heuristic(use_first(halving,delta_largest))))": 495,
"opt(dictionary(sliding_window(128),continued_fractions(binary)))": 477,
"opt(dictionary(sliding_window(128),continued_fractions(co_binary)))": 477,
"opt(dictionary(sliding_window(128),continued_fractions(dichotomic)))": 476,
"opt(dictionary(sliding_window(128),heuristic(use_first(halving,approximation))))": 474,
"opt(dictionary(sliding_window(128),heuristic(use_first(halving,delta_largest))))": 473,
"opt(dictionary(sliding_window(16),continued_fractions(binary)))": 443,
"opt(dictionary(sliding_window(16),continued_fractions(co_binary)))": 443,
"opt(dictionary(sliding_window(16),continued_fractions(dichotomic)))": 443,
"opt(dictionary(sliding_window(16),heuristic(use_first(halving,approximation))))": 445,
"opt(dictionary(sliding_window(16),heuristic(use_first(halving,delta_largest))))": 443,
"opt(dictionary(sliding_window(32),continued_fractions(binary)))": 446,
"opt(dictionary(sliding_window(32),continued_fractions(co_binary)))": 446,
"opt(dictionary(sliding_window(32),continued_fractions(dichotomic)))": 446,
"opt(dictionary(sliding_window(32),heuristic(use_first(halving,approximation))))": 450,
"opt(dictionary(sliding_window(32),heuristic(use_first(halving,delta_largest))))": 445,
"opt(dictionary(sliding_window(4),continued_fractions(binary)))": 474,
"opt(dictionary(sliding_window(4),continued_fractions(co_binary)))": 474,
"opt(dictionary(sliding_window(4),continued_fractions(dichotomic)))": 474,
"opt(dictionary(sliding_window(4),heuristic(use_first(halving,approximation))))": 474,
"opt(dictionary(sliding_window(4),heuristic(use_first(halving,delta_largest))))": 474,
"opt(dictionary(sliding_window(64),continued_fractions(binary)))": 450,
"opt(dictionary(sliding_window(64),continued_fractions(co_binary)))": 450,
"opt(dictionary(sliding_window(64),continued_fractions(dichotomic)))": 450,
"opt(dictionary(sliding_window(64),heuristic(use_first(halving,approximation))))": 453,
"opt(dictionary(sliding_window(64),heuristic(use_first(halving,delta_largest))))": 455,
"opt(dictionary(sliding_window(8),continued_fractions(binary)))": 450,
"opt(dictionary(sliding_window(8),continued_fractions(co_binary)))": 450,
"opt(dictionary(sliding_window(8),continued_fractions(dichotomic)))": 450,
"opt(dictionary(sliding_window(8),heuristic(use_first(halving,approximation))))": 452,
"opt(dictionary(sliding_window(8),heuristic(use_first(halving,delta_largest))))": 450,
"opt(runs(continued_fractions(binary)))": 445,
"opt(runs(continued_fractions(co_binary)))": 445,
"opt(runs(continued_fractions(dichotomic)))": 445,
"opt(runs(heuristic(use_first(halving,approximation))))": 444,
"opt(runs(heuristic(use_first(halving,delta_largest))))": 444
} addchain-0.4.0/alg/ensemble/testdata/p41417_field.golden 0000664 0000000 0000000 00000035321 15143052566 0022624 0 ustar 00root root 0000000 0000000 {
"opt(dictionary(hybrid(2,0),continued_fractions(binary)))": 620,
"opt(dictionary(hybrid(2,0),continued_fractions(co_binary)))": 620,
"opt(dictionary(hybrid(2,0),continued_fractions(dichotomic)))": 427,
"opt(dictionary(hybrid(2,0),heuristic(use_first(halving,approximation))))": 620,
"opt(dictionary(hybrid(2,0),heuristic(use_first(halving,delta_largest))))": 821,
"opt(dictionary(hybrid(2,16),continued_fractions(binary)))": 446,
"opt(dictionary(hybrid(2,16),continued_fractions(co_binary)))": 446,
"opt(dictionary(hybrid(2,16),continued_fractions(dichotomic)))": 446,
"opt(dictionary(hybrid(2,16),heuristic(use_first(halving,approximation))))": 446,
"opt(dictionary(hybrid(2,16),heuristic(use_first(halving,delta_largest))))": 446,
"opt(dictionary(hybrid(2,32),continued_fractions(binary)))": 435,
"opt(dictionary(hybrid(2,32),continued_fractions(co_binary)))": 435,
"opt(dictionary(hybrid(2,32),continued_fractions(dichotomic)))": 435,
"opt(dictionary(hybrid(2,32),heuristic(use_first(halving,approximation))))": 435,
"opt(dictionary(hybrid(2,32),heuristic(use_first(halving,delta_largest))))": 444,
"opt(dictionary(hybrid(2,64),continued_fractions(binary)))": 430,
"opt(dictionary(hybrid(2,64),continued_fractions(co_binary)))": 430,
"opt(dictionary(hybrid(2,64),continued_fractions(dichotomic)))": 430,
"opt(dictionary(hybrid(2,64),heuristic(use_first(halving,approximation))))": 430,
"opt(dictionary(hybrid(2,64),heuristic(use_first(halving,delta_largest))))": 448,
"opt(dictionary(hybrid(3,0),continued_fractions(binary)))": 620,
"opt(dictionary(hybrid(3,0),continued_fractions(co_binary)))": 620,
"opt(dictionary(hybrid(3,0),continued_fractions(dichotomic)))": 427,
"opt(dictionary(hybrid(3,0),heuristic(use_first(halving,approximation))))": 620,
"opt(dictionary(hybrid(3,0),heuristic(use_first(halving,delta_largest))))": 821,
"opt(dictionary(hybrid(3,16),continued_fractions(binary)))": 446,
"opt(dictionary(hybrid(3,16),continued_fractions(co_binary)))": 446,
"opt(dictionary(hybrid(3,16),continued_fractions(dichotomic)))": 446,
"opt(dictionary(hybrid(3,16),heuristic(use_first(halving,approximation))))": 446,
"opt(dictionary(hybrid(3,16),heuristic(use_first(halving,delta_largest))))": 446,
"opt(dictionary(hybrid(3,32),continued_fractions(binary)))": 435,
"opt(dictionary(hybrid(3,32),continued_fractions(co_binary)))": 435,
"opt(dictionary(hybrid(3,32),continued_fractions(dichotomic)))": 435,
"opt(dictionary(hybrid(3,32),heuristic(use_first(halving,approximation))))": 435,
"opt(dictionary(hybrid(3,32),heuristic(use_first(halving,delta_largest))))": 444,
"opt(dictionary(hybrid(3,64),continued_fractions(binary)))": 430,
"opt(dictionary(hybrid(3,64),continued_fractions(co_binary)))": 430,
"opt(dictionary(hybrid(3,64),continued_fractions(dichotomic)))": 430,
"opt(dictionary(hybrid(3,64),heuristic(use_first(halving,approximation))))": 430,
"opt(dictionary(hybrid(3,64),heuristic(use_first(halving,delta_largest))))": 448,
"opt(dictionary(hybrid(4,0),continued_fractions(binary)))": 620,
"opt(dictionary(hybrid(4,0),continued_fractions(co_binary)))": 620,
"opt(dictionary(hybrid(4,0),continued_fractions(dichotomic)))": 437,
"opt(dictionary(hybrid(4,0),heuristic(use_first(halving,approximation))))": 519,
"opt(dictionary(hybrid(4,0),heuristic(use_first(halving,delta_largest))))": 819,
"opt(dictionary(hybrid(4,16),continued_fractions(binary)))": 446,
"opt(dictionary(hybrid(4,16),continued_fractions(co_binary)))": 446,
"opt(dictionary(hybrid(4,16),continued_fractions(dichotomic)))": 446,
"opt(dictionary(hybrid(4,16),heuristic(use_first(halving,approximation))))": 445,
"opt(dictionary(hybrid(4,16),heuristic(use_first(halving,delta_largest))))": 445,
"opt(dictionary(hybrid(4,32),continued_fractions(binary)))": 434,
"opt(dictionary(hybrid(4,32),continued_fractions(co_binary)))": 434,
"opt(dictionary(hybrid(4,32),continued_fractions(dichotomic)))": 434,
"opt(dictionary(hybrid(4,32),heuristic(use_first(halving,approximation))))": 434,
"opt(dictionary(hybrid(4,32),heuristic(use_first(halving,delta_largest))))": 443,
"opt(dictionary(hybrid(4,64),continued_fractions(binary)))": 431,
"opt(dictionary(hybrid(4,64),continued_fractions(co_binary)))": 431,
"opt(dictionary(hybrid(4,64),continued_fractions(dichotomic)))": 430,
"opt(dictionary(hybrid(4,64),heuristic(use_first(halving,approximation))))": 429,
"opt(dictionary(hybrid(4,64),heuristic(use_first(halving,delta_largest))))": 448,
"opt(dictionary(hybrid(5,0),continued_fractions(binary)))": 620,
"opt(dictionary(hybrid(5,0),continued_fractions(co_binary)))": 620,
"opt(dictionary(hybrid(5,0),continued_fractions(dichotomic)))": 437,
"opt(dictionary(hybrid(5,0),heuristic(use_first(halving,approximation))))": 519,
"opt(dictionary(hybrid(5,0),heuristic(use_first(halving,delta_largest))))": 819,
"opt(dictionary(hybrid(5,16),continued_fractions(binary)))": 446,
"opt(dictionary(hybrid(5,16),continued_fractions(co_binary)))": 446,
"opt(dictionary(hybrid(5,16),continued_fractions(dichotomic)))": 446,
"opt(dictionary(hybrid(5,16),heuristic(use_first(halving,approximation))))": 445,
"opt(dictionary(hybrid(5,16),heuristic(use_first(halving,delta_largest))))": 445,
"opt(dictionary(hybrid(5,32),continued_fractions(binary)))": 434,
"opt(dictionary(hybrid(5,32),continued_fractions(co_binary)))": 434,
"opt(dictionary(hybrid(5,32),continued_fractions(dichotomic)))": 434,
"opt(dictionary(hybrid(5,32),heuristic(use_first(halving,approximation))))": 434,
"opt(dictionary(hybrid(5,32),heuristic(use_first(halving,delta_largest))))": 443,
"opt(dictionary(hybrid(5,64),continued_fractions(binary)))": 431,
"opt(dictionary(hybrid(5,64),continued_fractions(co_binary)))": 431,
"opt(dictionary(hybrid(5,64),continued_fractions(dichotomic)))": 430,
"opt(dictionary(hybrid(5,64),heuristic(use_first(halving,approximation))))": 429,
"opt(dictionary(hybrid(5,64),heuristic(use_first(halving,delta_largest))))": 448,
"opt(dictionary(hybrid(6,0),continued_fractions(binary)))": 620,
"opt(dictionary(hybrid(6,0),continued_fractions(co_binary)))": 620,
"opt(dictionary(hybrid(6,0),continued_fractions(dichotomic)))": 437,
"opt(dictionary(hybrid(6,0),heuristic(use_first(halving,approximation))))": 519,
"opt(dictionary(hybrid(6,0),heuristic(use_first(halving,delta_largest))))": 819,
"opt(dictionary(hybrid(6,16),continued_fractions(binary)))": 446,
"opt(dictionary(hybrid(6,16),continued_fractions(co_binary)))": 446,
"opt(dictionary(hybrid(6,16),continued_fractions(dichotomic)))": 446,
"opt(dictionary(hybrid(6,16),heuristic(use_first(halving,approximation))))": 445,
"opt(dictionary(hybrid(6,16),heuristic(use_first(halving,delta_largest))))": 445,
"opt(dictionary(hybrid(6,32),continued_fractions(binary)))": 434,
"opt(dictionary(hybrid(6,32),continued_fractions(co_binary)))": 434,
"opt(dictionary(hybrid(6,32),continued_fractions(dichotomic)))": 434,
"opt(dictionary(hybrid(6,32),heuristic(use_first(halving,approximation))))": 434,
"opt(dictionary(hybrid(6,32),heuristic(use_first(halving,delta_largest))))": 443,
"opt(dictionary(hybrid(6,64),continued_fractions(binary)))": 431,
"opt(dictionary(hybrid(6,64),continued_fractions(co_binary)))": 431,
"opt(dictionary(hybrid(6,64),continued_fractions(dichotomic)))": 430,
"opt(dictionary(hybrid(6,64),heuristic(use_first(halving,approximation))))": 429,
"opt(dictionary(hybrid(6,64),heuristic(use_first(halving,delta_largest))))": 448,
"opt(dictionary(hybrid(7,0),continued_fractions(binary)))": 620,
"opt(dictionary(hybrid(7,0),continued_fractions(co_binary)))": 620,
"opt(dictionary(hybrid(7,0),continued_fractions(dichotomic)))": 437,
"opt(dictionary(hybrid(7,0),heuristic(use_first(halving,approximation))))": 519,
"opt(dictionary(hybrid(7,0),heuristic(use_first(halving,delta_largest))))": 819,
"opt(dictionary(hybrid(7,16),continued_fractions(binary)))": 446,
"opt(dictionary(hybrid(7,16),continued_fractions(co_binary)))": 446,
"opt(dictionary(hybrid(7,16),continued_fractions(dichotomic)))": 446,
"opt(dictionary(hybrid(7,16),heuristic(use_first(halving,approximation))))": 445,
"opt(dictionary(hybrid(7,16),heuristic(use_first(halving,delta_largest))))": 445,
"opt(dictionary(hybrid(7,32),continued_fractions(binary)))": 434,
"opt(dictionary(hybrid(7,32),continued_fractions(co_binary)))": 434,
"opt(dictionary(hybrid(7,32),continued_fractions(dichotomic)))": 434,
"opt(dictionary(hybrid(7,32),heuristic(use_first(halving,approximation))))": 434,
"opt(dictionary(hybrid(7,32),heuristic(use_first(halving,delta_largest))))": 443,
"opt(dictionary(hybrid(7,64),continued_fractions(binary)))": 431,
"opt(dictionary(hybrid(7,64),continued_fractions(co_binary)))": 431,
"opt(dictionary(hybrid(7,64),continued_fractions(dichotomic)))": 430,
"opt(dictionary(hybrid(7,64),heuristic(use_first(halving,approximation))))": 429,
"opt(dictionary(hybrid(7,64),heuristic(use_first(halving,delta_largest))))": 448,
"opt(dictionary(hybrid(8,0),continued_fractions(binary)))": 620,
"opt(dictionary(hybrid(8,0),continued_fractions(co_binary)))": 620,
"opt(dictionary(hybrid(8,0),continued_fractions(dichotomic)))": 437,
"opt(dictionary(hybrid(8,0),heuristic(use_first(halving,approximation))))": 519,
"opt(dictionary(hybrid(8,0),heuristic(use_first(halving,delta_largest))))": 819,
"opt(dictionary(hybrid(8,16),continued_fractions(binary)))": 446,
"opt(dictionary(hybrid(8,16),continued_fractions(co_binary)))": 446,
"opt(dictionary(hybrid(8,16),continued_fractions(dichotomic)))": 446,
"opt(dictionary(hybrid(8,16),heuristic(use_first(halving,approximation))))": 445,
"opt(dictionary(hybrid(8,16),heuristic(use_first(halving,delta_largest))))": 445,
"opt(dictionary(hybrid(8,32),continued_fractions(binary)))": 434,
"opt(dictionary(hybrid(8,32),continued_fractions(co_binary)))": 434,
"opt(dictionary(hybrid(8,32),continued_fractions(dichotomic)))": 434,
"opt(dictionary(hybrid(8,32),heuristic(use_first(halving,approximation))))": 434,
"opt(dictionary(hybrid(8,32),heuristic(use_first(halving,delta_largest))))": 443,
"opt(dictionary(hybrid(8,64),continued_fractions(binary)))": 431,
"opt(dictionary(hybrid(8,64),continued_fractions(co_binary)))": 431,
"opt(dictionary(hybrid(8,64),continued_fractions(dichotomic)))": 430,
"opt(dictionary(hybrid(8,64),heuristic(use_first(halving,approximation))))": 429,
"opt(dictionary(hybrid(8,64),heuristic(use_first(halving,delta_largest))))": 448,
"opt(dictionary(run_length(0),continued_fractions(binary)))": 620,
"opt(dictionary(run_length(0),continued_fractions(co_binary)))": 620,
"opt(dictionary(run_length(0),continued_fractions(dichotomic)))": 427,
"opt(dictionary(run_length(0),heuristic(use_first(halving,approximation))))": 620,
"opt(dictionary(run_length(0),heuristic(use_first(halving,delta_largest))))": 821,
"opt(dictionary(run_length(128),continued_fractions(binary)))": 433,
"opt(dictionary(run_length(128),continued_fractions(co_binary)))": 433,
"opt(dictionary(run_length(128),continued_fractions(dichotomic)))": 428,
"opt(dictionary(run_length(128),heuristic(use_first(halving,approximation))))": 433,
"opt(dictionary(run_length(128),heuristic(use_first(halving,delta_largest))))": 519,
"opt(dictionary(run_length(16),continued_fractions(binary)))": 446,
"opt(dictionary(run_length(16),continued_fractions(co_binary)))": 446,
"opt(dictionary(run_length(16),continued_fractions(dichotomic)))": 446,
"opt(dictionary(run_length(16),heuristic(use_first(halving,approximation))))": 446,
"opt(dictionary(run_length(16),heuristic(use_first(halving,delta_largest))))": 446,
"opt(dictionary(run_length(32),continued_fractions(binary)))": 435,
"opt(dictionary(run_length(32),continued_fractions(co_binary)))": 435,
"opt(dictionary(run_length(32),continued_fractions(dichotomic)))": 435,
"opt(dictionary(run_length(32),heuristic(use_first(halving,approximation))))": 435,
"opt(dictionary(run_length(32),heuristic(use_first(halving,delta_largest))))": 444,
"opt(dictionary(run_length(64),continued_fractions(binary)))": 430,
"opt(dictionary(run_length(64),continued_fractions(co_binary)))": 430,
"opt(dictionary(run_length(64),continued_fractions(dichotomic)))": 430,
"opt(dictionary(run_length(64),heuristic(use_first(halving,approximation))))": 430,
"opt(dictionary(run_length(64),heuristic(use_first(halving,delta_largest))))": 448,
"opt(dictionary(sliding_window(128),continued_fractions(binary)))": 449,
"opt(dictionary(sliding_window(128),continued_fractions(co_binary)))": 449,
"opt(dictionary(sliding_window(128),continued_fractions(dichotomic)))": 445,
"opt(dictionary(sliding_window(128),heuristic(use_first(halving,approximation))))": 430,
"opt(dictionary(sliding_window(128),heuristic(use_first(halving,delta_largest))))": 507,
"opt(dictionary(sliding_window(16),continued_fractions(binary)))": 447,
"opt(dictionary(sliding_window(16),continued_fractions(co_binary)))": 447,
"opt(dictionary(sliding_window(16),continued_fractions(dichotomic)))": 446,
"opt(dictionary(sliding_window(16),heuristic(use_first(halving,approximation))))": 449,
"opt(dictionary(sliding_window(16),heuristic(use_first(halving,delta_largest))))": 449,
"opt(dictionary(sliding_window(32),continued_fractions(binary)))": 441,
"opt(dictionary(sliding_window(32),continued_fractions(co_binary)))": 441,
"opt(dictionary(sliding_window(32),continued_fractions(dichotomic)))": 437,
"opt(dictionary(sliding_window(32),heuristic(use_first(halving,approximation))))": 435,
"opt(dictionary(sliding_window(32),heuristic(use_first(halving,delta_largest))))": 451,
"opt(dictionary(sliding_window(4),continued_fractions(binary)))": 519,
"opt(dictionary(sliding_window(4),continued_fractions(co_binary)))": 519,
"opt(dictionary(sliding_window(4),continued_fractions(dichotomic)))": 519,
"opt(dictionary(sliding_window(4),heuristic(use_first(halving,approximation))))": 519,
"opt(dictionary(sliding_window(4),heuristic(use_first(halving,delta_largest))))": 519,
"opt(dictionary(sliding_window(64),continued_fractions(binary)))": 439,
"opt(dictionary(sliding_window(64),continued_fractions(co_binary)))": 439,
"opt(dictionary(sliding_window(64),continued_fractions(dichotomic)))": 440,
"opt(dictionary(sliding_window(64),heuristic(use_first(halving,approximation))))": 431,
"opt(dictionary(sliding_window(64),heuristic(use_first(halving,delta_largest))))": 449,
"opt(dictionary(sliding_window(8),continued_fractions(binary)))": 469,
"opt(dictionary(sliding_window(8),continued_fractions(co_binary)))": 469,
"opt(dictionary(sliding_window(8),continued_fractions(dichotomic)))": 468,
"opt(dictionary(sliding_window(8),heuristic(use_first(halving,approximation))))": 470,
"opt(dictionary(sliding_window(8),heuristic(use_first(halving,delta_largest))))": 470,
"opt(runs(continued_fractions(binary)))": 427,
"opt(runs(continued_fractions(co_binary)))": 427,
"opt(runs(continued_fractions(dichotomic)))": 426,
"opt(runs(heuristic(use_first(halving,approximation))))": 426,
"opt(runs(heuristic(use_first(halving,delta_largest))))": 429
} addchain-0.4.0/alg/ensemble/testdata/p511187_field.golden 0000664 0000000 0000000 00000035331 15143052566 0022713 0 ustar 00root root 0000000 0000000 {
"opt(dictionary(hybrid(2,0),continued_fractions(binary)))": 764,
"opt(dictionary(hybrid(2,0),continued_fractions(co_binary)))": 764,
"opt(dictionary(hybrid(2,0),continued_fractions(dichotomic)))": 527,
"opt(dictionary(hybrid(2,0),heuristic(use_first(halving,approximation))))": 764,
"opt(dictionary(hybrid(2,0),heuristic(use_first(halving,delta_largest))))": 1012,
"opt(dictionary(hybrid(2,16),continued_fractions(binary)))": 549,
"opt(dictionary(hybrid(2,16),continued_fractions(co_binary)))": 549,
"opt(dictionary(hybrid(2,16),continued_fractions(dichotomic)))": 549,
"opt(dictionary(hybrid(2,16),heuristic(use_first(halving,approximation))))": 549,
"opt(dictionary(hybrid(2,16),heuristic(use_first(halving,delta_largest))))": 551,
"opt(dictionary(hybrid(2,32),continued_fractions(binary)))": 534,
"opt(dictionary(hybrid(2,32),continued_fractions(co_binary)))": 534,
"opt(dictionary(hybrid(2,32),continued_fractions(dichotomic)))": 534,
"opt(dictionary(hybrid(2,32),heuristic(use_first(halving,approximation))))": 534,
"opt(dictionary(hybrid(2,32),heuristic(use_first(halving,delta_largest))))": 539,
"opt(dictionary(hybrid(2,64),continued_fractions(binary)))": 531,
"opt(dictionary(hybrid(2,64),continued_fractions(co_binary)))": 531,
"opt(dictionary(hybrid(2,64),continued_fractions(dichotomic)))": 528,
"opt(dictionary(hybrid(2,64),heuristic(use_first(halving,approximation))))": 531,
"opt(dictionary(hybrid(2,64),heuristic(use_first(halving,delta_largest))))": 562,
"opt(dictionary(hybrid(3,0),continued_fractions(binary)))": 764,
"opt(dictionary(hybrid(3,0),continued_fractions(co_binary)))": 764,
"opt(dictionary(hybrid(3,0),continued_fractions(dichotomic)))": 527,
"opt(dictionary(hybrid(3,0),heuristic(use_first(halving,approximation))))": 764,
"opt(dictionary(hybrid(3,0),heuristic(use_first(halving,delta_largest))))": 1012,
"opt(dictionary(hybrid(3,16),continued_fractions(binary)))": 549,
"opt(dictionary(hybrid(3,16),continued_fractions(co_binary)))": 549,
"opt(dictionary(hybrid(3,16),continued_fractions(dichotomic)))": 549,
"opt(dictionary(hybrid(3,16),heuristic(use_first(halving,approximation))))": 549,
"opt(dictionary(hybrid(3,16),heuristic(use_first(halving,delta_largest))))": 551,
"opt(dictionary(hybrid(3,32),continued_fractions(binary)))": 534,
"opt(dictionary(hybrid(3,32),continued_fractions(co_binary)))": 534,
"opt(dictionary(hybrid(3,32),continued_fractions(dichotomic)))": 534,
"opt(dictionary(hybrid(3,32),heuristic(use_first(halving,approximation))))": 534,
"opt(dictionary(hybrid(3,32),heuristic(use_first(halving,delta_largest))))": 539,
"opt(dictionary(hybrid(3,64),continued_fractions(binary)))": 531,
"opt(dictionary(hybrid(3,64),continued_fractions(co_binary)))": 531,
"opt(dictionary(hybrid(3,64),continued_fractions(dichotomic)))": 528,
"opt(dictionary(hybrid(3,64),heuristic(use_first(halving,approximation))))": 531,
"opt(dictionary(hybrid(3,64),heuristic(use_first(halving,delta_largest))))": 562,
"opt(dictionary(hybrid(4,0),continued_fractions(binary)))": 764,
"opt(dictionary(hybrid(4,0),continued_fractions(co_binary)))": 764,
"opt(dictionary(hybrid(4,0),continued_fractions(dichotomic)))": 527,
"opt(dictionary(hybrid(4,0),heuristic(use_first(halving,approximation))))": 764,
"opt(dictionary(hybrid(4,0),heuristic(use_first(halving,delta_largest))))": 1012,
"opt(dictionary(hybrid(4,16),continued_fractions(binary)))": 549,
"opt(dictionary(hybrid(4,16),continued_fractions(co_binary)))": 549,
"opt(dictionary(hybrid(4,16),continued_fractions(dichotomic)))": 549,
"opt(dictionary(hybrid(4,16),heuristic(use_first(halving,approximation))))": 549,
"opt(dictionary(hybrid(4,16),heuristic(use_first(halving,delta_largest))))": 551,
"opt(dictionary(hybrid(4,32),continued_fractions(binary)))": 534,
"opt(dictionary(hybrid(4,32),continued_fractions(co_binary)))": 534,
"opt(dictionary(hybrid(4,32),continued_fractions(dichotomic)))": 534,
"opt(dictionary(hybrid(4,32),heuristic(use_first(halving,approximation))))": 534,
"opt(dictionary(hybrid(4,32),heuristic(use_first(halving,delta_largest))))": 539,
"opt(dictionary(hybrid(4,64),continued_fractions(binary)))": 531,
"opt(dictionary(hybrid(4,64),continued_fractions(co_binary)))": 531,
"opt(dictionary(hybrid(4,64),continued_fractions(dichotomic)))": 528,
"opt(dictionary(hybrid(4,64),heuristic(use_first(halving,approximation))))": 531,
"opt(dictionary(hybrid(4,64),heuristic(use_first(halving,delta_largest))))": 562,
"opt(dictionary(hybrid(5,0),continued_fractions(binary)))": 764,
"opt(dictionary(hybrid(5,0),continued_fractions(co_binary)))": 764,
"opt(dictionary(hybrid(5,0),continued_fractions(dichotomic)))": 527,
"opt(dictionary(hybrid(5,0),heuristic(use_first(halving,approximation))))": 764,
"opt(dictionary(hybrid(5,0),heuristic(use_first(halving,delta_largest))))": 1012,
"opt(dictionary(hybrid(5,16),continued_fractions(binary)))": 549,
"opt(dictionary(hybrid(5,16),continued_fractions(co_binary)))": 549,
"opt(dictionary(hybrid(5,16),continued_fractions(dichotomic)))": 549,
"opt(dictionary(hybrid(5,16),heuristic(use_first(halving,approximation))))": 549,
"opt(dictionary(hybrid(5,16),heuristic(use_first(halving,delta_largest))))": 551,
"opt(dictionary(hybrid(5,32),continued_fractions(binary)))": 534,
"opt(dictionary(hybrid(5,32),continued_fractions(co_binary)))": 534,
"opt(dictionary(hybrid(5,32),continued_fractions(dichotomic)))": 534,
"opt(dictionary(hybrid(5,32),heuristic(use_first(halving,approximation))))": 534,
"opt(dictionary(hybrid(5,32),heuristic(use_first(halving,delta_largest))))": 539,
"opt(dictionary(hybrid(5,64),continued_fractions(binary)))": 531,
"opt(dictionary(hybrid(5,64),continued_fractions(co_binary)))": 531,
"opt(dictionary(hybrid(5,64),continued_fractions(dichotomic)))": 528,
"opt(dictionary(hybrid(5,64),heuristic(use_first(halving,approximation))))": 531,
"opt(dictionary(hybrid(5,64),heuristic(use_first(halving,delta_largest))))": 562,
"opt(dictionary(hybrid(6,0),continued_fractions(binary)))": 764,
"opt(dictionary(hybrid(6,0),continued_fractions(co_binary)))": 764,
"opt(dictionary(hybrid(6,0),continued_fractions(dichotomic)))": 528,
"opt(dictionary(hybrid(6,0),heuristic(use_first(halving,approximation))))": 600,
"opt(dictionary(hybrid(6,0),heuristic(use_first(halving,delta_largest))))": 1009,
"opt(dictionary(hybrid(6,16),continued_fractions(binary)))": 550,
"opt(dictionary(hybrid(6,16),continued_fractions(co_binary)))": 550,
"opt(dictionary(hybrid(6,16),continued_fractions(dichotomic)))": 550,
"opt(dictionary(hybrid(6,16),heuristic(use_first(halving,approximation))))": 549,
"opt(dictionary(hybrid(6,16),heuristic(use_first(halving,delta_largest))))": 551,
"opt(dictionary(hybrid(6,32),continued_fractions(binary)))": 538,
"opt(dictionary(hybrid(6,32),continued_fractions(co_binary)))": 538,
"opt(dictionary(hybrid(6,32),continued_fractions(dichotomic)))": 537,
"opt(dictionary(hybrid(6,32),heuristic(use_first(halving,approximation))))": 536,
"opt(dictionary(hybrid(6,32),heuristic(use_first(halving,delta_largest))))": 540,
"opt(dictionary(hybrid(6,64),continued_fractions(binary)))": 531,
"opt(dictionary(hybrid(6,64),continued_fractions(co_binary)))": 531,
"opt(dictionary(hybrid(6,64),continued_fractions(dichotomic)))": 528,
"opt(dictionary(hybrid(6,64),heuristic(use_first(halving,approximation))))": 531,
"opt(dictionary(hybrid(6,64),heuristic(use_first(halving,delta_largest))))": 563,
"opt(dictionary(hybrid(7,0),continued_fractions(binary)))": 764,
"opt(dictionary(hybrid(7,0),continued_fractions(co_binary)))": 764,
"opt(dictionary(hybrid(7,0),continued_fractions(dichotomic)))": 565,
"opt(dictionary(hybrid(7,0),heuristic(use_first(halving,approximation))))": 587,
"opt(dictionary(hybrid(7,0),heuristic(use_first(halving,delta_largest))))": 1006,
"opt(dictionary(hybrid(7,16),continued_fractions(binary)))": 548,
"opt(dictionary(hybrid(7,16),continued_fractions(co_binary)))": 548,
"opt(dictionary(hybrid(7,16),continued_fractions(dichotomic)))": 548,
"opt(dictionary(hybrid(7,16),heuristic(use_first(halving,approximation))))": 548,
"opt(dictionary(hybrid(7,16),heuristic(use_first(halving,delta_largest))))": 551,
"opt(dictionary(hybrid(7,32),continued_fractions(binary)))": 536,
"opt(dictionary(hybrid(7,32),continued_fractions(co_binary)))": 536,
"opt(dictionary(hybrid(7,32),continued_fractions(dichotomic)))": 536,
"opt(dictionary(hybrid(7,32),heuristic(use_first(halving,approximation))))": 535,
"opt(dictionary(hybrid(7,32),heuristic(use_first(halving,delta_largest))))": 539,
"opt(dictionary(hybrid(7,64),continued_fractions(binary)))": 530,
"opt(dictionary(hybrid(7,64),continued_fractions(co_binary)))": 530,
"opt(dictionary(hybrid(7,64),continued_fractions(dichotomic)))": 528,
"opt(dictionary(hybrid(7,64),heuristic(use_first(halving,approximation))))": 530,
"opt(dictionary(hybrid(7,64),heuristic(use_first(halving,delta_largest))))": 562,
"opt(dictionary(hybrid(8,0),continued_fractions(binary)))": 764,
"opt(dictionary(hybrid(8,0),continued_fractions(co_binary)))": 764,
"opt(dictionary(hybrid(8,0),continued_fractions(dichotomic)))": 565,
"opt(dictionary(hybrid(8,0),heuristic(use_first(halving,approximation))))": 587,
"opt(dictionary(hybrid(8,0),heuristic(use_first(halving,delta_largest))))": 1006,
"opt(dictionary(hybrid(8,16),continued_fractions(binary)))": 548,
"opt(dictionary(hybrid(8,16),continued_fractions(co_binary)))": 548,
"opt(dictionary(hybrid(8,16),continued_fractions(dichotomic)))": 548,
"opt(dictionary(hybrid(8,16),heuristic(use_first(halving,approximation))))": 548,
"opt(dictionary(hybrid(8,16),heuristic(use_first(halving,delta_largest))))": 551,
"opt(dictionary(hybrid(8,32),continued_fractions(binary)))": 536,
"opt(dictionary(hybrid(8,32),continued_fractions(co_binary)))": 536,
"opt(dictionary(hybrid(8,32),continued_fractions(dichotomic)))": 536,
"opt(dictionary(hybrid(8,32),heuristic(use_first(halving,approximation))))": 535,
"opt(dictionary(hybrid(8,32),heuristic(use_first(halving,delta_largest))))": 539,
"opt(dictionary(hybrid(8,64),continued_fractions(binary)))": 530,
"opt(dictionary(hybrid(8,64),continued_fractions(co_binary)))": 530,
"opt(dictionary(hybrid(8,64),continued_fractions(dichotomic)))": 528,
"opt(dictionary(hybrid(8,64),heuristic(use_first(halving,approximation))))": 530,
"opt(dictionary(hybrid(8,64),heuristic(use_first(halving,delta_largest))))": 562,
"opt(dictionary(run_length(0),continued_fractions(binary)))": 764,
"opt(dictionary(run_length(0),continued_fractions(co_binary)))": 764,
"opt(dictionary(run_length(0),continued_fractions(dichotomic)))": 527,
"opt(dictionary(run_length(0),heuristic(use_first(halving,approximation))))": 764,
"opt(dictionary(run_length(0),heuristic(use_first(halving,delta_largest))))": 1012,
"opt(dictionary(run_length(128),continued_fractions(binary)))": 534,
"opt(dictionary(run_length(128),continued_fractions(co_binary)))": 534,
"opt(dictionary(run_length(128),continued_fractions(dichotomic)))": 526,
"opt(dictionary(run_length(128),heuristic(use_first(halving,approximation))))": 534,
"opt(dictionary(run_length(128),heuristic(use_first(halving,delta_largest))))": 623,
"opt(dictionary(run_length(16),continued_fractions(binary)))": 549,
"opt(dictionary(run_length(16),continued_fractions(co_binary)))": 549,
"opt(dictionary(run_length(16),continued_fractions(dichotomic)))": 549,
"opt(dictionary(run_length(16),heuristic(use_first(halving,approximation))))": 549,
"opt(dictionary(run_length(16),heuristic(use_first(halving,delta_largest))))": 551,
"opt(dictionary(run_length(32),continued_fractions(binary)))": 534,
"opt(dictionary(run_length(32),continued_fractions(co_binary)))": 534,
"opt(dictionary(run_length(32),continued_fractions(dichotomic)))": 534,
"opt(dictionary(run_length(32),heuristic(use_first(halving,approximation))))": 534,
"opt(dictionary(run_length(32),heuristic(use_first(halving,delta_largest))))": 539,
"opt(dictionary(run_length(64),continued_fractions(binary)))": 531,
"opt(dictionary(run_length(64),continued_fractions(co_binary)))": 531,
"opt(dictionary(run_length(64),continued_fractions(dichotomic)))": 528,
"opt(dictionary(run_length(64),heuristic(use_first(halving,approximation))))": 531,
"opt(dictionary(run_length(64),heuristic(use_first(halving,delta_largest))))": 562,
"opt(dictionary(sliding_window(128),continued_fractions(binary)))": 580,
"opt(dictionary(sliding_window(128),continued_fractions(co_binary)))": 580,
"opt(dictionary(sliding_window(128),continued_fractions(dichotomic)))": 540,
"opt(dictionary(sliding_window(128),heuristic(use_first(halving,approximation))))": 542,
"opt(dictionary(sliding_window(128),heuristic(use_first(halving,delta_largest))))": 633,
"opt(dictionary(sliding_window(16),continued_fractions(binary)))": 552,
"opt(dictionary(sliding_window(16),continued_fractions(co_binary)))": 552,
"opt(dictionary(sliding_window(16),continued_fractions(dichotomic)))": 550,
"opt(dictionary(sliding_window(16),heuristic(use_first(halving,approximation))))": 549,
"opt(dictionary(sliding_window(16),heuristic(use_first(halving,delta_largest))))": 549,
"opt(dictionary(sliding_window(32),continued_fractions(binary)))": 544,
"opt(dictionary(sliding_window(32),continued_fractions(co_binary)))": 544,
"opt(dictionary(sliding_window(32),continued_fractions(dichotomic)))": 539,
"opt(dictionary(sliding_window(32),heuristic(use_first(halving,approximation))))": 542,
"opt(dictionary(sliding_window(32),heuristic(use_first(halving,delta_largest))))": 549,
"opt(dictionary(sliding_window(4),continued_fractions(binary)))": 640,
"opt(dictionary(sliding_window(4),continued_fractions(co_binary)))": 640,
"opt(dictionary(sliding_window(4),continued_fractions(dichotomic)))": 640,
"opt(dictionary(sliding_window(4),heuristic(use_first(halving,approximation))))": 640,
"opt(dictionary(sliding_window(4),heuristic(use_first(halving,delta_largest))))": 640,
"opt(dictionary(sliding_window(64),continued_fractions(binary)))": 554,
"opt(dictionary(sliding_window(64),continued_fractions(co_binary)))": 554,
"opt(dictionary(sliding_window(64),continued_fractions(dichotomic)))": 541,
"opt(dictionary(sliding_window(64),heuristic(use_first(halving,approximation))))": 538,
"opt(dictionary(sliding_window(64),heuristic(use_first(halving,delta_largest))))": 573,
"opt(dictionary(sliding_window(8),continued_fractions(binary)))": 578,
"opt(dictionary(sliding_window(8),continued_fractions(co_binary)))": 578,
"opt(dictionary(sliding_window(8),continued_fractions(dichotomic)))": 578,
"opt(dictionary(sliding_window(8),heuristic(use_first(halving,approximation))))": 578,
"opt(dictionary(sliding_window(8),heuristic(use_first(halving,delta_largest))))": 578,
"opt(runs(continued_fractions(binary)))": 527,
"opt(runs(continued_fractions(co_binary)))": 527,
"opt(runs(continued_fractions(dichotomic)))": 525,
"opt(runs(heuristic(use_first(halving,approximation))))": 526,
"opt(runs(heuristic(use_first(halving,delta_largest))))": 528
} addchain-0.4.0/alg/ensemble/testdata/secp192k1_field.golden 0000664 0000000 0000000 00000035321 15143052566 0023406 0 ustar 00root root 0000000 0000000 {
"opt(dictionary(hybrid(2,0),continued_fractions(binary)))": 210,
"opt(dictionary(hybrid(2,0),continued_fractions(co_binary)))": 210,
"opt(dictionary(hybrid(2,0),continued_fractions(dichotomic)))": 206,
"opt(dictionary(hybrid(2,0),heuristic(use_first(halving,approximation))))": 210,
"opt(dictionary(hybrid(2,0),heuristic(use_first(halving,delta_largest))))": 328,
"opt(dictionary(hybrid(2,16),continued_fractions(binary)))": 213,
"opt(dictionary(hybrid(2,16),continued_fractions(co_binary)))": 213,
"opt(dictionary(hybrid(2,16),continued_fractions(dichotomic)))": 212,
"opt(dictionary(hybrid(2,16),heuristic(use_first(halving,approximation))))": 213,
"opt(dictionary(hybrid(2,16),heuristic(use_first(halving,delta_largest))))": 217,
"opt(dictionary(hybrid(2,32),continued_fractions(binary)))": 208,
"opt(dictionary(hybrid(2,32),continued_fractions(co_binary)))": 208,
"opt(dictionary(hybrid(2,32),continued_fractions(dichotomic)))": 208,
"opt(dictionary(hybrid(2,32),heuristic(use_first(halving,approximation))))": 208,
"opt(dictionary(hybrid(2,32),heuristic(use_first(halving,delta_largest))))": 208,
"opt(dictionary(hybrid(2,64),continued_fractions(binary)))": 207,
"opt(dictionary(hybrid(2,64),continued_fractions(co_binary)))": 207,
"opt(dictionary(hybrid(2,64),continued_fractions(dichotomic)))": 207,
"opt(dictionary(hybrid(2,64),heuristic(use_first(halving,approximation))))": 207,
"opt(dictionary(hybrid(2,64),heuristic(use_first(halving,delta_largest))))": 210,
"opt(dictionary(hybrid(3,0),continued_fractions(binary)))": 209,
"opt(dictionary(hybrid(3,0),continued_fractions(co_binary)))": 209,
"opt(dictionary(hybrid(3,0),continued_fractions(dichotomic)))": 205,
"opt(dictionary(hybrid(3,0),heuristic(use_first(halving,approximation))))": 209,
"opt(dictionary(hybrid(3,0),heuristic(use_first(halving,delta_largest))))": 327,
"opt(dictionary(hybrid(3,16),continued_fractions(binary)))": 212,
"opt(dictionary(hybrid(3,16),continued_fractions(co_binary)))": 212,
"opt(dictionary(hybrid(3,16),continued_fractions(dichotomic)))": 211,
"opt(dictionary(hybrid(3,16),heuristic(use_first(halving,approximation))))": 212,
"opt(dictionary(hybrid(3,16),heuristic(use_first(halving,delta_largest))))": 216,
"opt(dictionary(hybrid(3,32),continued_fractions(binary)))": 207,
"opt(dictionary(hybrid(3,32),continued_fractions(co_binary)))": 207,
"opt(dictionary(hybrid(3,32),continued_fractions(dichotomic)))": 207,
"opt(dictionary(hybrid(3,32),heuristic(use_first(halving,approximation))))": 207,
"opt(dictionary(hybrid(3,32),heuristic(use_first(halving,delta_largest))))": 207,
"opt(dictionary(hybrid(3,64),continued_fractions(binary)))": 206,
"opt(dictionary(hybrid(3,64),continued_fractions(co_binary)))": 206,
"opt(dictionary(hybrid(3,64),continued_fractions(dichotomic)))": 206,
"opt(dictionary(hybrid(3,64),heuristic(use_first(halving,approximation))))": 206,
"opt(dictionary(hybrid(3,64),heuristic(use_first(halving,delta_largest))))": 209,
"opt(dictionary(hybrid(4,0),continued_fractions(binary)))": 210,
"opt(dictionary(hybrid(4,0),continued_fractions(co_binary)))": 210,
"opt(dictionary(hybrid(4,0),continued_fractions(dichotomic)))": 206,
"opt(dictionary(hybrid(4,0),heuristic(use_first(halving,approximation))))": 210,
"opt(dictionary(hybrid(4,0),heuristic(use_first(halving,delta_largest))))": 328,
"opt(dictionary(hybrid(4,16),continued_fractions(binary)))": 214,
"opt(dictionary(hybrid(4,16),continued_fractions(co_binary)))": 214,
"opt(dictionary(hybrid(4,16),continued_fractions(dichotomic)))": 212,
"opt(dictionary(hybrid(4,16),heuristic(use_first(halving,approximation))))": 212,
"opt(dictionary(hybrid(4,16),heuristic(use_first(halving,delta_largest))))": 218,
"opt(dictionary(hybrid(4,32),continued_fractions(binary)))": 208,
"opt(dictionary(hybrid(4,32),continued_fractions(co_binary)))": 208,
"opt(dictionary(hybrid(4,32),continued_fractions(dichotomic)))": 208,
"opt(dictionary(hybrid(4,32),heuristic(use_first(halving,approximation))))": 208,
"opt(dictionary(hybrid(4,32),heuristic(use_first(halving,delta_largest))))": 208,
"opt(dictionary(hybrid(4,64),continued_fractions(binary)))": 207,
"opt(dictionary(hybrid(4,64),continued_fractions(co_binary)))": 207,
"opt(dictionary(hybrid(4,64),continued_fractions(dichotomic)))": 207,
"opt(dictionary(hybrid(4,64),heuristic(use_first(halving,approximation))))": 207,
"opt(dictionary(hybrid(4,64),heuristic(use_first(halving,delta_largest))))": 210,
"opt(dictionary(hybrid(5,0),continued_fractions(binary)))": 210,
"opt(dictionary(hybrid(5,0),continued_fractions(co_binary)))": 210,
"opt(dictionary(hybrid(5,0),continued_fractions(dichotomic)))": 206,
"opt(dictionary(hybrid(5,0),heuristic(use_first(halving,approximation))))": 210,
"opt(dictionary(hybrid(5,0),heuristic(use_first(halving,delta_largest))))": 328,
"opt(dictionary(hybrid(5,16),continued_fractions(binary)))": 214,
"opt(dictionary(hybrid(5,16),continued_fractions(co_binary)))": 214,
"opt(dictionary(hybrid(5,16),continued_fractions(dichotomic)))": 213,
"opt(dictionary(hybrid(5,16),heuristic(use_first(halving,approximation))))": 213,
"opt(dictionary(hybrid(5,16),heuristic(use_first(halving,delta_largest))))": 216,
"opt(dictionary(hybrid(5,32),continued_fractions(binary)))": 208,
"opt(dictionary(hybrid(5,32),continued_fractions(co_binary)))": 208,
"opt(dictionary(hybrid(5,32),continued_fractions(dichotomic)))": 208,
"opt(dictionary(hybrid(5,32),heuristic(use_first(halving,approximation))))": 208,
"opt(dictionary(hybrid(5,32),heuristic(use_first(halving,delta_largest))))": 208,
"opt(dictionary(hybrid(5,64),continued_fractions(binary)))": 207,
"opt(dictionary(hybrid(5,64),continued_fractions(co_binary)))": 207,
"opt(dictionary(hybrid(5,64),continued_fractions(dichotomic)))": 207,
"opt(dictionary(hybrid(5,64),heuristic(use_first(halving,approximation))))": 207,
"opt(dictionary(hybrid(5,64),heuristic(use_first(halving,delta_largest))))": 210,
"opt(dictionary(hybrid(6,0),continued_fractions(binary)))": 210,
"opt(dictionary(hybrid(6,0),continued_fractions(co_binary)))": 210,
"opt(dictionary(hybrid(6,0),continued_fractions(dichotomic)))": 206,
"opt(dictionary(hybrid(6,0),heuristic(use_first(halving,approximation))))": 211,
"opt(dictionary(hybrid(6,0),heuristic(use_first(halving,delta_largest))))": 329,
"opt(dictionary(hybrid(6,16),continued_fractions(binary)))": 214,
"opt(dictionary(hybrid(6,16),continued_fractions(co_binary)))": 214,
"opt(dictionary(hybrid(6,16),continued_fractions(dichotomic)))": 213,
"opt(dictionary(hybrid(6,16),heuristic(use_first(halving,approximation))))": 212,
"opt(dictionary(hybrid(6,16),heuristic(use_first(halving,delta_largest))))": 214,
"opt(dictionary(hybrid(6,32),continued_fractions(binary)))": 208,
"opt(dictionary(hybrid(6,32),continued_fractions(co_binary)))": 208,
"opt(dictionary(hybrid(6,32),continued_fractions(dichotomic)))": 208,
"opt(dictionary(hybrid(6,32),heuristic(use_first(halving,approximation))))": 209,
"opt(dictionary(hybrid(6,32),heuristic(use_first(halving,delta_largest))))": 209,
"opt(dictionary(hybrid(6,64),continued_fractions(binary)))": 207,
"opt(dictionary(hybrid(6,64),continued_fractions(co_binary)))": 207,
"opt(dictionary(hybrid(6,64),continued_fractions(dichotomic)))": 207,
"opt(dictionary(hybrid(6,64),heuristic(use_first(halving,approximation))))": 208,
"opt(dictionary(hybrid(6,64),heuristic(use_first(halving,delta_largest))))": 211,
"opt(dictionary(hybrid(7,0),continued_fractions(binary)))": 210,
"opt(dictionary(hybrid(7,0),continued_fractions(co_binary)))": 210,
"opt(dictionary(hybrid(7,0),continued_fractions(dichotomic)))": 206,
"opt(dictionary(hybrid(7,0),heuristic(use_first(halving,approximation))))": 211,
"opt(dictionary(hybrid(7,0),heuristic(use_first(halving,delta_largest))))": 329,
"opt(dictionary(hybrid(7,16),continued_fractions(binary)))": 214,
"opt(dictionary(hybrid(7,16),continued_fractions(co_binary)))": 214,
"opt(dictionary(hybrid(7,16),continued_fractions(dichotomic)))": 214,
"opt(dictionary(hybrid(7,16),heuristic(use_first(halving,approximation))))": 213,
"opt(dictionary(hybrid(7,16),heuristic(use_first(halving,delta_largest))))": 213,
"opt(dictionary(hybrid(7,32),continued_fractions(binary)))": 208,
"opt(dictionary(hybrid(7,32),continued_fractions(co_binary)))": 208,
"opt(dictionary(hybrid(7,32),continued_fractions(dichotomic)))": 208,
"opt(dictionary(hybrid(7,32),heuristic(use_first(halving,approximation))))": 209,
"opt(dictionary(hybrid(7,32),heuristic(use_first(halving,delta_largest))))": 208,
"opt(dictionary(hybrid(7,64),continued_fractions(binary)))": 208,
"opt(dictionary(hybrid(7,64),continued_fractions(co_binary)))": 208,
"opt(dictionary(hybrid(7,64),continued_fractions(dichotomic)))": 208,
"opt(dictionary(hybrid(7,64),heuristic(use_first(halving,approximation))))": 208,
"opt(dictionary(hybrid(7,64),heuristic(use_first(halving,delta_largest))))": 209,
"opt(dictionary(hybrid(8,0),continued_fractions(binary)))": 212,
"opt(dictionary(hybrid(8,0),continued_fractions(co_binary)))": 212,
"opt(dictionary(hybrid(8,0),continued_fractions(dichotomic)))": 209,
"opt(dictionary(hybrid(8,0),heuristic(use_first(halving,approximation))))": 212,
"opt(dictionary(hybrid(8,0),heuristic(use_first(halving,delta_largest))))": 329,
"opt(dictionary(hybrid(8,16),continued_fractions(binary)))": 214,
"opt(dictionary(hybrid(8,16),continued_fractions(co_binary)))": 214,
"opt(dictionary(hybrid(8,16),continued_fractions(dichotomic)))": 214,
"opt(dictionary(hybrid(8,16),heuristic(use_first(halving,approximation))))": 213,
"opt(dictionary(hybrid(8,16),heuristic(use_first(halving,delta_largest))))": 213,
"opt(dictionary(hybrid(8,32),continued_fractions(binary)))": 209,
"opt(dictionary(hybrid(8,32),continued_fractions(co_binary)))": 209,
"opt(dictionary(hybrid(8,32),continued_fractions(dichotomic)))": 209,
"opt(dictionary(hybrid(8,32),heuristic(use_first(halving,approximation))))": 210,
"opt(dictionary(hybrid(8,32),heuristic(use_first(halving,delta_largest))))": 209,
"opt(dictionary(hybrid(8,64),continued_fractions(binary)))": 208,
"opt(dictionary(hybrid(8,64),continued_fractions(co_binary)))": 208,
"opt(dictionary(hybrid(8,64),continued_fractions(dichotomic)))": 208,
"opt(dictionary(hybrid(8,64),heuristic(use_first(halving,approximation))))": 209,
"opt(dictionary(hybrid(8,64),heuristic(use_first(halving,delta_largest))))": 210,
"opt(dictionary(run_length(0),continued_fractions(binary)))": 210,
"opt(dictionary(run_length(0),continued_fractions(co_binary)))": 210,
"opt(dictionary(run_length(0),continued_fractions(dichotomic)))": 206,
"opt(dictionary(run_length(0),heuristic(use_first(halving,approximation))))": 210,
"opt(dictionary(run_length(0),heuristic(use_first(halving,delta_largest))))": 328,
"opt(dictionary(run_length(128),continued_fractions(binary)))": 209,
"opt(dictionary(run_length(128),continued_fractions(co_binary)))": 209,
"opt(dictionary(run_length(128),continued_fractions(dichotomic)))": 208,
"opt(dictionary(run_length(128),heuristic(use_first(halving,approximation))))": 209,
"opt(dictionary(run_length(128),heuristic(use_first(halving,delta_largest))))": 274,
"opt(dictionary(run_length(16),continued_fractions(binary)))": 213,
"opt(dictionary(run_length(16),continued_fractions(co_binary)))": 213,
"opt(dictionary(run_length(16),continued_fractions(dichotomic)))": 212,
"opt(dictionary(run_length(16),heuristic(use_first(halving,approximation))))": 213,
"opt(dictionary(run_length(16),heuristic(use_first(halving,delta_largest))))": 217,
"opt(dictionary(run_length(32),continued_fractions(binary)))": 208,
"opt(dictionary(run_length(32),continued_fractions(co_binary)))": 208,
"opt(dictionary(run_length(32),continued_fractions(dichotomic)))": 208,
"opt(dictionary(run_length(32),heuristic(use_first(halving,approximation))))": 208,
"opt(dictionary(run_length(32),heuristic(use_first(halving,delta_largest))))": 208,
"opt(dictionary(run_length(64),continued_fractions(binary)))": 207,
"opt(dictionary(run_length(64),continued_fractions(co_binary)))": 207,
"opt(dictionary(run_length(64),continued_fractions(dichotomic)))": 207,
"opt(dictionary(run_length(64),heuristic(use_first(halving,approximation))))": 207,
"opt(dictionary(run_length(64),heuristic(use_first(halving,delta_largest))))": 210,
"opt(dictionary(sliding_window(128),continued_fractions(binary)))": 236,
"opt(dictionary(sliding_window(128),continued_fractions(co_binary)))": 236,
"opt(dictionary(sliding_window(128),continued_fractions(dichotomic)))": 239,
"opt(dictionary(sliding_window(128),heuristic(use_first(halving,approximation))))": 216,
"opt(dictionary(sliding_window(128),heuristic(use_first(halving,delta_largest))))": 213,
"opt(dictionary(sliding_window(16),continued_fractions(binary)))": 213,
"opt(dictionary(sliding_window(16),continued_fractions(co_binary)))": 213,
"opt(dictionary(sliding_window(16),continued_fractions(dichotomic)))": 213,
"opt(dictionary(sliding_window(16),heuristic(use_first(halving,approximation))))": 212,
"opt(dictionary(sliding_window(16),heuristic(use_first(halving,delta_largest))))": 214,
"opt(dictionary(sliding_window(32),continued_fractions(binary)))": 214,
"opt(dictionary(sliding_window(32),continued_fractions(co_binary)))": 214,
"opt(dictionary(sliding_window(32),continued_fractions(dichotomic)))": 212,
"opt(dictionary(sliding_window(32),heuristic(use_first(halving,approximation))))": 213,
"opt(dictionary(sliding_window(32),heuristic(use_first(halving,delta_largest))))": 217,
"opt(dictionary(sliding_window(4),continued_fractions(binary)))": 241,
"opt(dictionary(sliding_window(4),continued_fractions(co_binary)))": 241,
"opt(dictionary(sliding_window(4),continued_fractions(dichotomic)))": 241,
"opt(dictionary(sliding_window(4),heuristic(use_first(halving,approximation))))": 241,
"opt(dictionary(sliding_window(4),heuristic(use_first(halving,delta_largest))))": 241,
"opt(dictionary(sliding_window(64),continued_fractions(binary)))": 237,
"opt(dictionary(sliding_window(64),continued_fractions(co_binary)))": 237,
"opt(dictionary(sliding_window(64),continued_fractions(dichotomic)))": 222,
"opt(dictionary(sliding_window(64),heuristic(use_first(halving,approximation))))": 216,
"opt(dictionary(sliding_window(64),heuristic(use_first(halving,delta_largest))))": 213,
"opt(dictionary(sliding_window(8),continued_fractions(binary)))": 220,
"opt(dictionary(sliding_window(8),continued_fractions(co_binary)))": 220,
"opt(dictionary(sliding_window(8),continued_fractions(dichotomic)))": 220,
"opt(dictionary(sliding_window(8),heuristic(use_first(halving,approximation))))": 222,
"opt(dictionary(sliding_window(8),heuristic(use_first(halving,delta_largest))))": 222,
"opt(runs(continued_fractions(binary)))": 206,
"opt(runs(continued_fractions(co_binary)))": 206,
"opt(runs(continued_fractions(dichotomic)))": 206,
"opt(runs(heuristic(use_first(halving,approximation))))": 207,
"opt(runs(heuristic(use_first(halving,delta_largest))))": 207
} addchain-0.4.0/alg/ensemble/testdata/secp224k1_field.golden 0000664 0000000 0000000 00000035321 15143052566 0023402 0 ustar 00root root 0000000 0000000 {
"opt(dictionary(hybrid(2,0),continued_fractions(binary)))": 249,
"opt(dictionary(hybrid(2,0),continued_fractions(co_binary)))": 249,
"opt(dictionary(hybrid(2,0),continued_fractions(dichotomic)))": 240,
"opt(dictionary(hybrid(2,0),heuristic(use_first(halving,approximation))))": 249,
"opt(dictionary(hybrid(2,0),heuristic(use_first(halving,delta_largest))))": 397,
"opt(dictionary(hybrid(2,16),continued_fractions(binary)))": 248,
"opt(dictionary(hybrid(2,16),continued_fractions(co_binary)))": 248,
"opt(dictionary(hybrid(2,16),continued_fractions(dichotomic)))": 247,
"opt(dictionary(hybrid(2,16),heuristic(use_first(halving,approximation))))": 248,
"opt(dictionary(hybrid(2,16),heuristic(use_first(halving,delta_largest))))": 252,
"opt(dictionary(hybrid(2,32),continued_fractions(binary)))": 242,
"opt(dictionary(hybrid(2,32),continued_fractions(co_binary)))": 242,
"opt(dictionary(hybrid(2,32),continued_fractions(dichotomic)))": 242,
"opt(dictionary(hybrid(2,32),heuristic(use_first(halving,approximation))))": 242,
"opt(dictionary(hybrid(2,32),heuristic(use_first(halving,delta_largest))))": 242,
"opt(dictionary(hybrid(2,64),continued_fractions(binary)))": 241,
"opt(dictionary(hybrid(2,64),continued_fractions(co_binary)))": 241,
"opt(dictionary(hybrid(2,64),continued_fractions(dichotomic)))": 241,
"opt(dictionary(hybrid(2,64),heuristic(use_first(halving,approximation))))": 241,
"opt(dictionary(hybrid(2,64),heuristic(use_first(halving,delta_largest))))": 271,
"opt(dictionary(hybrid(3,0),continued_fractions(binary)))": 248,
"opt(dictionary(hybrid(3,0),continued_fractions(co_binary)))": 248,
"opt(dictionary(hybrid(3,0),continued_fractions(dichotomic)))": 240,
"opt(dictionary(hybrid(3,0),heuristic(use_first(halving,approximation))))": 246,
"opt(dictionary(hybrid(3,0),heuristic(use_first(halving,delta_largest))))": 395,
"opt(dictionary(hybrid(3,16),continued_fractions(binary)))": 247,
"opt(dictionary(hybrid(3,16),continued_fractions(co_binary)))": 247,
"opt(dictionary(hybrid(3,16),continued_fractions(dichotomic)))": 246,
"opt(dictionary(hybrid(3,16),heuristic(use_first(halving,approximation))))": 247,
"opt(dictionary(hybrid(3,16),heuristic(use_first(halving,delta_largest))))": 251,
"opt(dictionary(hybrid(3,32),continued_fractions(binary)))": 241,
"opt(dictionary(hybrid(3,32),continued_fractions(co_binary)))": 241,
"opt(dictionary(hybrid(3,32),continued_fractions(dichotomic)))": 241,
"opt(dictionary(hybrid(3,32),heuristic(use_first(halving,approximation))))": 241,
"opt(dictionary(hybrid(3,32),heuristic(use_first(halving,delta_largest))))": 241,
"opt(dictionary(hybrid(3,64),continued_fractions(binary)))": 240,
"opt(dictionary(hybrid(3,64),continued_fractions(co_binary)))": 240,
"opt(dictionary(hybrid(3,64),continued_fractions(dichotomic)))": 240,
"opt(dictionary(hybrid(3,64),heuristic(use_first(halving,approximation))))": 240,
"opt(dictionary(hybrid(3,64),heuristic(use_first(halving,delta_largest))))": 270,
"opt(dictionary(hybrid(4,0),continued_fractions(binary)))": 247,
"opt(dictionary(hybrid(4,0),continued_fractions(co_binary)))": 247,
"opt(dictionary(hybrid(4,0),continued_fractions(dichotomic)))": 241,
"opt(dictionary(hybrid(4,0),heuristic(use_first(halving,approximation))))": 245,
"opt(dictionary(hybrid(4,0),heuristic(use_first(halving,delta_largest))))": 398,
"opt(dictionary(hybrid(4,16),continued_fractions(binary)))": 249,
"opt(dictionary(hybrid(4,16),continued_fractions(co_binary)))": 249,
"opt(dictionary(hybrid(4,16),continued_fractions(dichotomic)))": 247,
"opt(dictionary(hybrid(4,16),heuristic(use_first(halving,approximation))))": 247,
"opt(dictionary(hybrid(4,16),heuristic(use_first(halving,delta_largest))))": 252,
"opt(dictionary(hybrid(4,32),continued_fractions(binary)))": 240,
"opt(dictionary(hybrid(4,32),continued_fractions(co_binary)))": 240,
"opt(dictionary(hybrid(4,32),continued_fractions(dichotomic)))": 240,
"opt(dictionary(hybrid(4,32),heuristic(use_first(halving,approximation))))": 242,
"opt(dictionary(hybrid(4,32),heuristic(use_first(halving,delta_largest))))": 242,
"opt(dictionary(hybrid(4,64),continued_fractions(binary)))": 240,
"opt(dictionary(hybrid(4,64),continued_fractions(co_binary)))": 240,
"opt(dictionary(hybrid(4,64),continued_fractions(dichotomic)))": 240,
"opt(dictionary(hybrid(4,64),heuristic(use_first(halving,approximation))))": 241,
"opt(dictionary(hybrid(4,64),heuristic(use_first(halving,delta_largest))))": 270,
"opt(dictionary(hybrid(5,0),continued_fractions(binary)))": 245,
"opt(dictionary(hybrid(5,0),continued_fractions(co_binary)))": 245,
"opt(dictionary(hybrid(5,0),continued_fractions(dichotomic)))": 238,
"opt(dictionary(hybrid(5,0),heuristic(use_first(halving,approximation))))": 245,
"opt(dictionary(hybrid(5,0),heuristic(use_first(halving,delta_largest))))": 396,
"opt(dictionary(hybrid(5,16),continued_fractions(binary)))": 246,
"opt(dictionary(hybrid(5,16),continued_fractions(co_binary)))": 246,
"opt(dictionary(hybrid(5,16),continued_fractions(dichotomic)))": 245,
"opt(dictionary(hybrid(5,16),heuristic(use_first(halving,approximation))))": 246,
"opt(dictionary(hybrid(5,16),heuristic(use_first(halving,delta_largest))))": 249,
"opt(dictionary(hybrid(5,32),continued_fractions(binary)))": 241,
"opt(dictionary(hybrid(5,32),continued_fractions(co_binary)))": 241,
"opt(dictionary(hybrid(5,32),continued_fractions(dichotomic)))": 241,
"opt(dictionary(hybrid(5,32),heuristic(use_first(halving,approximation))))": 240,
"opt(dictionary(hybrid(5,32),heuristic(use_first(halving,delta_largest))))": 240,
"opt(dictionary(hybrid(5,64),continued_fractions(binary)))": 239,
"opt(dictionary(hybrid(5,64),continued_fractions(co_binary)))": 239,
"opt(dictionary(hybrid(5,64),continued_fractions(dichotomic)))": 239,
"opt(dictionary(hybrid(5,64),heuristic(use_first(halving,approximation))))": 240,
"opt(dictionary(hybrid(5,64),heuristic(use_first(halving,delta_largest))))": 268,
"opt(dictionary(hybrid(6,0),continued_fractions(binary)))": 247,
"opt(dictionary(hybrid(6,0),continued_fractions(co_binary)))": 247,
"opt(dictionary(hybrid(6,0),continued_fractions(dichotomic)))": 241,
"opt(dictionary(hybrid(6,0),heuristic(use_first(halving,approximation))))": 244,
"opt(dictionary(hybrid(6,0),heuristic(use_first(halving,delta_largest))))": 391,
"opt(dictionary(hybrid(6,16),continued_fractions(binary)))": 251,
"opt(dictionary(hybrid(6,16),continued_fractions(co_binary)))": 251,
"opt(dictionary(hybrid(6,16),continued_fractions(dichotomic)))": 250,
"opt(dictionary(hybrid(6,16),heuristic(use_first(halving,approximation))))": 247,
"opt(dictionary(hybrid(6,16),heuristic(use_first(halving,delta_largest))))": 249,
"opt(dictionary(hybrid(6,32),continued_fractions(binary)))": 241,
"opt(dictionary(hybrid(6,32),continued_fractions(co_binary)))": 241,
"opt(dictionary(hybrid(6,32),continued_fractions(dichotomic)))": 241,
"opt(dictionary(hybrid(6,32),heuristic(use_first(halving,approximation))))": 242,
"opt(dictionary(hybrid(6,32),heuristic(use_first(halving,delta_largest))))": 241,
"opt(dictionary(hybrid(6,64),continued_fractions(binary)))": 239,
"opt(dictionary(hybrid(6,64),continued_fractions(co_binary)))": 239,
"opt(dictionary(hybrid(6,64),continued_fractions(dichotomic)))": 239,
"opt(dictionary(hybrid(6,64),heuristic(use_first(halving,approximation))))": 240,
"opt(dictionary(hybrid(6,64),heuristic(use_first(halving,delta_largest))))": 269,
"opt(dictionary(hybrid(7,0),continued_fractions(binary)))": 247,
"opt(dictionary(hybrid(7,0),continued_fractions(co_binary)))": 247,
"opt(dictionary(hybrid(7,0),continued_fractions(dichotomic)))": 241,
"opt(dictionary(hybrid(7,0),heuristic(use_first(halving,approximation))))": 244,
"opt(dictionary(hybrid(7,0),heuristic(use_first(halving,delta_largest))))": 391,
"opt(dictionary(hybrid(7,16),continued_fractions(binary)))": 251,
"opt(dictionary(hybrid(7,16),continued_fractions(co_binary)))": 251,
"opt(dictionary(hybrid(7,16),continued_fractions(dichotomic)))": 250,
"opt(dictionary(hybrid(7,16),heuristic(use_first(halving,approximation))))": 247,
"opt(dictionary(hybrid(7,16),heuristic(use_first(halving,delta_largest))))": 249,
"opt(dictionary(hybrid(7,32),continued_fractions(binary)))": 241,
"opt(dictionary(hybrid(7,32),continued_fractions(co_binary)))": 241,
"opt(dictionary(hybrid(7,32),continued_fractions(dichotomic)))": 241,
"opt(dictionary(hybrid(7,32),heuristic(use_first(halving,approximation))))": 242,
"opt(dictionary(hybrid(7,32),heuristic(use_first(halving,delta_largest))))": 241,
"opt(dictionary(hybrid(7,64),continued_fractions(binary)))": 239,
"opt(dictionary(hybrid(7,64),continued_fractions(co_binary)))": 239,
"opt(dictionary(hybrid(7,64),continued_fractions(dichotomic)))": 239,
"opt(dictionary(hybrid(7,64),heuristic(use_first(halving,approximation))))": 240,
"opt(dictionary(hybrid(7,64),heuristic(use_first(halving,delta_largest))))": 269,
"opt(dictionary(hybrid(8,0),continued_fractions(binary)))": 248,
"opt(dictionary(hybrid(8,0),continued_fractions(co_binary)))": 248,
"opt(dictionary(hybrid(8,0),continued_fractions(dichotomic)))": 241,
"opt(dictionary(hybrid(8,0),heuristic(use_first(halving,approximation))))": 244,
"opt(dictionary(hybrid(8,0),heuristic(use_first(halving,delta_largest))))": 390,
"opt(dictionary(hybrid(8,16),continued_fractions(binary)))": 249,
"opt(dictionary(hybrid(8,16),continued_fractions(co_binary)))": 249,
"opt(dictionary(hybrid(8,16),continued_fractions(dichotomic)))": 249,
"opt(dictionary(hybrid(8,16),heuristic(use_first(halving,approximation))))": 246,
"opt(dictionary(hybrid(8,16),heuristic(use_first(halving,delta_largest))))": 245,
"opt(dictionary(hybrid(8,32),continued_fractions(binary)))": 243,
"opt(dictionary(hybrid(8,32),continued_fractions(co_binary)))": 243,
"opt(dictionary(hybrid(8,32),continued_fractions(dichotomic)))": 242,
"opt(dictionary(hybrid(8,32),heuristic(use_first(halving,approximation))))": 244,
"opt(dictionary(hybrid(8,32),heuristic(use_first(halving,delta_largest))))": 241,
"opt(dictionary(hybrid(8,64),continued_fractions(binary)))": 244,
"opt(dictionary(hybrid(8,64),continued_fractions(co_binary)))": 244,
"opt(dictionary(hybrid(8,64),continued_fractions(dichotomic)))": 242,
"opt(dictionary(hybrid(8,64),heuristic(use_first(halving,approximation))))": 242,
"opt(dictionary(hybrid(8,64),heuristic(use_first(halving,delta_largest))))": 269,
"opt(dictionary(run_length(0),continued_fractions(binary)))": 249,
"opt(dictionary(run_length(0),continued_fractions(co_binary)))": 249,
"opt(dictionary(run_length(0),continued_fractions(dichotomic)))": 240,
"opt(dictionary(run_length(0),heuristic(use_first(halving,approximation))))": 249,
"opt(dictionary(run_length(0),heuristic(use_first(halving,delta_largest))))": 397,
"opt(dictionary(run_length(128),continued_fractions(binary)))": 241,
"opt(dictionary(run_length(128),continued_fractions(co_binary)))": 241,
"opt(dictionary(run_length(128),continued_fractions(dichotomic)))": 241,
"opt(dictionary(run_length(128),heuristic(use_first(halving,approximation))))": 241,
"opt(dictionary(run_length(128),heuristic(use_first(halving,delta_largest))))": 273,
"opt(dictionary(run_length(16),continued_fractions(binary)))": 248,
"opt(dictionary(run_length(16),continued_fractions(co_binary)))": 248,
"opt(dictionary(run_length(16),continued_fractions(dichotomic)))": 247,
"opt(dictionary(run_length(16),heuristic(use_first(halving,approximation))))": 248,
"opt(dictionary(run_length(16),heuristic(use_first(halving,delta_largest))))": 252,
"opt(dictionary(run_length(32),continued_fractions(binary)))": 242,
"opt(dictionary(run_length(32),continued_fractions(co_binary)))": 242,
"opt(dictionary(run_length(32),continued_fractions(dichotomic)))": 242,
"opt(dictionary(run_length(32),heuristic(use_first(halving,approximation))))": 242,
"opt(dictionary(run_length(32),heuristic(use_first(halving,delta_largest))))": 242,
"opt(dictionary(run_length(64),continued_fractions(binary)))": 241,
"opt(dictionary(run_length(64),continued_fractions(co_binary)))": 241,
"opt(dictionary(run_length(64),continued_fractions(dichotomic)))": 241,
"opt(dictionary(run_length(64),heuristic(use_first(halving,approximation))))": 241,
"opt(dictionary(run_length(64),heuristic(use_first(halving,delta_largest))))": 271,
"opt(dictionary(sliding_window(128),continued_fractions(binary)))": 287,
"opt(dictionary(sliding_window(128),continued_fractions(co_binary)))": 287,
"opt(dictionary(sliding_window(128),continued_fractions(dichotomic)))": 272,
"opt(dictionary(sliding_window(128),heuristic(use_first(halving,approximation))))": 275,
"opt(dictionary(sliding_window(128),heuristic(use_first(halving,delta_largest))))": 279,
"opt(dictionary(sliding_window(16),continued_fractions(binary)))": 248,
"opt(dictionary(sliding_window(16),continued_fractions(co_binary)))": 248,
"opt(dictionary(sliding_window(16),continued_fractions(dichotomic)))": 248,
"opt(dictionary(sliding_window(16),heuristic(use_first(halving,approximation))))": 248,
"opt(dictionary(sliding_window(16),heuristic(use_first(halving,delta_largest))))": 247,
"opt(dictionary(sliding_window(32),continued_fractions(binary)))": 248,
"opt(dictionary(sliding_window(32),continued_fractions(co_binary)))": 248,
"opt(dictionary(sliding_window(32),continued_fractions(dichotomic)))": 244,
"opt(dictionary(sliding_window(32),heuristic(use_first(halving,approximation))))": 248,
"opt(dictionary(sliding_window(32),heuristic(use_first(halving,delta_largest))))": 249,
"opt(dictionary(sliding_window(4),continued_fractions(binary)))": 282,
"opt(dictionary(sliding_window(4),continued_fractions(co_binary)))": 282,
"opt(dictionary(sliding_window(4),continued_fractions(dichotomic)))": 282,
"opt(dictionary(sliding_window(4),heuristic(use_first(halving,approximation))))": 282,
"opt(dictionary(sliding_window(4),heuristic(use_first(halving,delta_largest))))": 282,
"opt(dictionary(sliding_window(64),continued_fractions(binary)))": 253,
"opt(dictionary(sliding_window(64),continued_fractions(co_binary)))": 253,
"opt(dictionary(sliding_window(64),continued_fractions(dichotomic)))": 254,
"opt(dictionary(sliding_window(64),heuristic(use_first(halving,approximation))))": 247,
"opt(dictionary(sliding_window(64),heuristic(use_first(halving,delta_largest))))": 248,
"opt(dictionary(sliding_window(8),continued_fractions(binary)))": 257,
"opt(dictionary(sliding_window(8),continued_fractions(co_binary)))": 257,
"opt(dictionary(sliding_window(8),continued_fractions(dichotomic)))": 257,
"opt(dictionary(sliding_window(8),heuristic(use_first(halving,approximation))))": 257,
"opt(dictionary(sliding_window(8),heuristic(use_first(halving,delta_largest))))": 256,
"opt(runs(continued_fractions(binary)))": 240,
"opt(runs(continued_fractions(co_binary)))": 240,
"opt(runs(continued_fractions(dichotomic)))": 240,
"opt(runs(heuristic(use_first(halving,approximation))))": 241,
"opt(runs(heuristic(use_first(halving,delta_largest))))": 241
} addchain-0.4.0/alg/ensemble/testdata/secp256k1_field.golden 0000664 0000000 0000000 00000035321 15143052566 0023407 0 ustar 00root root 0000000 0000000 {
"opt(dictionary(hybrid(2,0),continued_fractions(binary)))": 277,
"opt(dictionary(hybrid(2,0),continued_fractions(co_binary)))": 277,
"opt(dictionary(hybrid(2,0),continued_fractions(dichotomic)))": 270,
"opt(dictionary(hybrid(2,0),heuristic(use_first(halving,approximation))))": 277,
"opt(dictionary(hybrid(2,0),heuristic(use_first(halving,delta_largest))))": 457,
"opt(dictionary(hybrid(2,16),continued_fractions(binary)))": 278,
"opt(dictionary(hybrid(2,16),continued_fractions(co_binary)))": 278,
"opt(dictionary(hybrid(2,16),continued_fractions(dichotomic)))": 278,
"opt(dictionary(hybrid(2,16),heuristic(use_first(halving,approximation))))": 278,
"opt(dictionary(hybrid(2,16),heuristic(use_first(halving,delta_largest))))": 280,
"opt(dictionary(hybrid(2,32),continued_fractions(binary)))": 272,
"opt(dictionary(hybrid(2,32),continued_fractions(co_binary)))": 272,
"opt(dictionary(hybrid(2,32),continued_fractions(dichotomic)))": 272,
"opt(dictionary(hybrid(2,32),heuristic(use_first(halving,approximation))))": 272,
"opt(dictionary(hybrid(2,32),heuristic(use_first(halving,delta_largest))))": 276,
"opt(dictionary(hybrid(2,64),continued_fractions(binary)))": 270,
"opt(dictionary(hybrid(2,64),continued_fractions(co_binary)))": 270,
"opt(dictionary(hybrid(2,64),continued_fractions(dichotomic)))": 270,
"opt(dictionary(hybrid(2,64),heuristic(use_first(halving,approximation))))": 270,
"opt(dictionary(hybrid(2,64),heuristic(use_first(halving,delta_largest))))": 277,
"opt(dictionary(hybrid(3,0),continued_fractions(binary)))": 277,
"opt(dictionary(hybrid(3,0),continued_fractions(co_binary)))": 277,
"opt(dictionary(hybrid(3,0),continued_fractions(dichotomic)))": 270,
"opt(dictionary(hybrid(3,0),heuristic(use_first(halving,approximation))))": 277,
"opt(dictionary(hybrid(3,0),heuristic(use_first(halving,delta_largest))))": 458,
"opt(dictionary(hybrid(3,16),continued_fractions(binary)))": 278,
"opt(dictionary(hybrid(3,16),continued_fractions(co_binary)))": 278,
"opt(dictionary(hybrid(3,16),continued_fractions(dichotomic)))": 278,
"opt(dictionary(hybrid(3,16),heuristic(use_first(halving,approximation))))": 278,
"opt(dictionary(hybrid(3,16),heuristic(use_first(halving,delta_largest))))": 280,
"opt(dictionary(hybrid(3,32),continued_fractions(binary)))": 272,
"opt(dictionary(hybrid(3,32),continued_fractions(co_binary)))": 272,
"opt(dictionary(hybrid(3,32),continued_fractions(dichotomic)))": 272,
"opt(dictionary(hybrid(3,32),heuristic(use_first(halving,approximation))))": 273,
"opt(dictionary(hybrid(3,32),heuristic(use_first(halving,delta_largest))))": 277,
"opt(dictionary(hybrid(3,64),continued_fractions(binary)))": 270,
"opt(dictionary(hybrid(3,64),continued_fractions(co_binary)))": 270,
"opt(dictionary(hybrid(3,64),continued_fractions(dichotomic)))": 270,
"opt(dictionary(hybrid(3,64),heuristic(use_first(halving,approximation))))": 271,
"opt(dictionary(hybrid(3,64),heuristic(use_first(halving,delta_largest))))": 278,
"opt(dictionary(hybrid(4,0),continued_fractions(binary)))": 279,
"opt(dictionary(hybrid(4,0),continued_fractions(co_binary)))": 279,
"opt(dictionary(hybrid(4,0),continued_fractions(dichotomic)))": 270,
"opt(dictionary(hybrid(4,0),heuristic(use_first(halving,approximation))))": 275,
"opt(dictionary(hybrid(4,0),heuristic(use_first(halving,delta_largest))))": 456,
"opt(dictionary(hybrid(4,16),continued_fractions(binary)))": 279,
"opt(dictionary(hybrid(4,16),continued_fractions(co_binary)))": 279,
"opt(dictionary(hybrid(4,16),continued_fractions(dichotomic)))": 279,
"opt(dictionary(hybrid(4,16),heuristic(use_first(halving,approximation))))": 278,
"opt(dictionary(hybrid(4,16),heuristic(use_first(halving,delta_largest))))": 280,
"opt(dictionary(hybrid(4,32),continued_fractions(binary)))": 272,
"opt(dictionary(hybrid(4,32),continued_fractions(co_binary)))": 272,
"opt(dictionary(hybrid(4,32),continued_fractions(dichotomic)))": 272,
"opt(dictionary(hybrid(4,32),heuristic(use_first(halving,approximation))))": 272,
"opt(dictionary(hybrid(4,32),heuristic(use_first(halving,delta_largest))))": 276,
"opt(dictionary(hybrid(4,64),continued_fractions(binary)))": 270,
"opt(dictionary(hybrid(4,64),continued_fractions(co_binary)))": 270,
"opt(dictionary(hybrid(4,64),continued_fractions(dichotomic)))": 270,
"opt(dictionary(hybrid(4,64),heuristic(use_first(halving,approximation))))": 270,
"opt(dictionary(hybrid(4,64),heuristic(use_first(halving,delta_largest))))": 278,
"opt(dictionary(hybrid(5,0),continued_fractions(binary)))": 279,
"opt(dictionary(hybrid(5,0),continued_fractions(co_binary)))": 279,
"opt(dictionary(hybrid(5,0),continued_fractions(dichotomic)))": 270,
"opt(dictionary(hybrid(5,0),heuristic(use_first(halving,approximation))))": 275,
"opt(dictionary(hybrid(5,0),heuristic(use_first(halving,delta_largest))))": 456,
"opt(dictionary(hybrid(5,16),continued_fractions(binary)))": 279,
"opt(dictionary(hybrid(5,16),continued_fractions(co_binary)))": 279,
"opt(dictionary(hybrid(5,16),continued_fractions(dichotomic)))": 279,
"opt(dictionary(hybrid(5,16),heuristic(use_first(halving,approximation))))": 278,
"opt(dictionary(hybrid(5,16),heuristic(use_first(halving,delta_largest))))": 280,
"opt(dictionary(hybrid(5,32),continued_fractions(binary)))": 272,
"opt(dictionary(hybrid(5,32),continued_fractions(co_binary)))": 272,
"opt(dictionary(hybrid(5,32),continued_fractions(dichotomic)))": 272,
"opt(dictionary(hybrid(5,32),heuristic(use_first(halving,approximation))))": 272,
"opt(dictionary(hybrid(5,32),heuristic(use_first(halving,delta_largest))))": 276,
"opt(dictionary(hybrid(5,64),continued_fractions(binary)))": 270,
"opt(dictionary(hybrid(5,64),continued_fractions(co_binary)))": 270,
"opt(dictionary(hybrid(5,64),continued_fractions(dichotomic)))": 270,
"opt(dictionary(hybrid(5,64),heuristic(use_first(halving,approximation))))": 270,
"opt(dictionary(hybrid(5,64),heuristic(use_first(halving,delta_largest))))": 278,
"opt(dictionary(hybrid(6,0),continued_fractions(binary)))": 279,
"opt(dictionary(hybrid(6,0),continued_fractions(co_binary)))": 279,
"opt(dictionary(hybrid(6,0),continued_fractions(dichotomic)))": 270,
"opt(dictionary(hybrid(6,0),heuristic(use_first(halving,approximation))))": 275,
"opt(dictionary(hybrid(6,0),heuristic(use_first(halving,delta_largest))))": 456,
"opt(dictionary(hybrid(6,16),continued_fractions(binary)))": 279,
"opt(dictionary(hybrid(6,16),continued_fractions(co_binary)))": 279,
"opt(dictionary(hybrid(6,16),continued_fractions(dichotomic)))": 279,
"opt(dictionary(hybrid(6,16),heuristic(use_first(halving,approximation))))": 278,
"opt(dictionary(hybrid(6,16),heuristic(use_first(halving,delta_largest))))": 280,
"opt(dictionary(hybrid(6,32),continued_fractions(binary)))": 272,
"opt(dictionary(hybrid(6,32),continued_fractions(co_binary)))": 272,
"opt(dictionary(hybrid(6,32),continued_fractions(dichotomic)))": 272,
"opt(dictionary(hybrid(6,32),heuristic(use_first(halving,approximation))))": 272,
"opt(dictionary(hybrid(6,32),heuristic(use_first(halving,delta_largest))))": 276,
"opt(dictionary(hybrid(6,64),continued_fractions(binary)))": 270,
"opt(dictionary(hybrid(6,64),continued_fractions(co_binary)))": 270,
"opt(dictionary(hybrid(6,64),continued_fractions(dichotomic)))": 270,
"opt(dictionary(hybrid(6,64),heuristic(use_first(halving,approximation))))": 270,
"opt(dictionary(hybrid(6,64),heuristic(use_first(halving,delta_largest))))": 278,
"opt(dictionary(hybrid(7,0),continued_fractions(binary)))": 279,
"opt(dictionary(hybrid(7,0),continued_fractions(co_binary)))": 279,
"opt(dictionary(hybrid(7,0),continued_fractions(dichotomic)))": 270,
"opt(dictionary(hybrid(7,0),heuristic(use_first(halving,approximation))))": 275,
"opt(dictionary(hybrid(7,0),heuristic(use_first(halving,delta_largest))))": 456,
"opt(dictionary(hybrid(7,16),continued_fractions(binary)))": 279,
"opt(dictionary(hybrid(7,16),continued_fractions(co_binary)))": 279,
"opt(dictionary(hybrid(7,16),continued_fractions(dichotomic)))": 279,
"opt(dictionary(hybrid(7,16),heuristic(use_first(halving,approximation))))": 278,
"opt(dictionary(hybrid(7,16),heuristic(use_first(halving,delta_largest))))": 280,
"opt(dictionary(hybrid(7,32),continued_fractions(binary)))": 272,
"opt(dictionary(hybrid(7,32),continued_fractions(co_binary)))": 272,
"opt(dictionary(hybrid(7,32),continued_fractions(dichotomic)))": 272,
"opt(dictionary(hybrid(7,32),heuristic(use_first(halving,approximation))))": 272,
"opt(dictionary(hybrid(7,32),heuristic(use_first(halving,delta_largest))))": 276,
"opt(dictionary(hybrid(7,64),continued_fractions(binary)))": 270,
"opt(dictionary(hybrid(7,64),continued_fractions(co_binary)))": 270,
"opt(dictionary(hybrid(7,64),continued_fractions(dichotomic)))": 270,
"opt(dictionary(hybrid(7,64),heuristic(use_first(halving,approximation))))": 270,
"opt(dictionary(hybrid(7,64),heuristic(use_first(halving,delta_largest))))": 278,
"opt(dictionary(hybrid(8,0),continued_fractions(binary)))": 279,
"opt(dictionary(hybrid(8,0),continued_fractions(co_binary)))": 279,
"opt(dictionary(hybrid(8,0),continued_fractions(dichotomic)))": 270,
"opt(dictionary(hybrid(8,0),heuristic(use_first(halving,approximation))))": 275,
"opt(dictionary(hybrid(8,0),heuristic(use_first(halving,delta_largest))))": 456,
"opt(dictionary(hybrid(8,16),continued_fractions(binary)))": 279,
"opt(dictionary(hybrid(8,16),continued_fractions(co_binary)))": 279,
"opt(dictionary(hybrid(8,16),continued_fractions(dichotomic)))": 279,
"opt(dictionary(hybrid(8,16),heuristic(use_first(halving,approximation))))": 278,
"opt(dictionary(hybrid(8,16),heuristic(use_first(halving,delta_largest))))": 280,
"opt(dictionary(hybrid(8,32),continued_fractions(binary)))": 272,
"opt(dictionary(hybrid(8,32),continued_fractions(co_binary)))": 272,
"opt(dictionary(hybrid(8,32),continued_fractions(dichotomic)))": 272,
"opt(dictionary(hybrid(8,32),heuristic(use_first(halving,approximation))))": 272,
"opt(dictionary(hybrid(8,32),heuristic(use_first(halving,delta_largest))))": 276,
"opt(dictionary(hybrid(8,64),continued_fractions(binary)))": 270,
"opt(dictionary(hybrid(8,64),continued_fractions(co_binary)))": 270,
"opt(dictionary(hybrid(8,64),continued_fractions(dichotomic)))": 270,
"opt(dictionary(hybrid(8,64),heuristic(use_first(halving,approximation))))": 270,
"opt(dictionary(hybrid(8,64),heuristic(use_first(halving,delta_largest))))": 278,
"opt(dictionary(run_length(0),continued_fractions(binary)))": 277,
"opt(dictionary(run_length(0),continued_fractions(co_binary)))": 277,
"opt(dictionary(run_length(0),continued_fractions(dichotomic)))": 270,
"opt(dictionary(run_length(0),heuristic(use_first(halving,approximation))))": 277,
"opt(dictionary(run_length(0),heuristic(use_first(halving,delta_largest))))": 457,
"opt(dictionary(run_length(128),continued_fractions(binary)))": 271,
"opt(dictionary(run_length(128),continued_fractions(co_binary)))": 271,
"opt(dictionary(run_length(128),continued_fractions(dichotomic)))": 271,
"opt(dictionary(run_length(128),heuristic(use_first(halving,approximation))))": 271,
"opt(dictionary(run_length(128),heuristic(use_first(halving,delta_largest))))": 315,
"opt(dictionary(run_length(16),continued_fractions(binary)))": 278,
"opt(dictionary(run_length(16),continued_fractions(co_binary)))": 278,
"opt(dictionary(run_length(16),continued_fractions(dichotomic)))": 278,
"opt(dictionary(run_length(16),heuristic(use_first(halving,approximation))))": 278,
"opt(dictionary(run_length(16),heuristic(use_first(halving,delta_largest))))": 280,
"opt(dictionary(run_length(32),continued_fractions(binary)))": 272,
"opt(dictionary(run_length(32),continued_fractions(co_binary)))": 272,
"opt(dictionary(run_length(32),continued_fractions(dichotomic)))": 272,
"opt(dictionary(run_length(32),heuristic(use_first(halving,approximation))))": 272,
"opt(dictionary(run_length(32),heuristic(use_first(halving,delta_largest))))": 276,
"opt(dictionary(run_length(64),continued_fractions(binary)))": 270,
"opt(dictionary(run_length(64),continued_fractions(co_binary)))": 270,
"opt(dictionary(run_length(64),continued_fractions(dichotomic)))": 270,
"opt(dictionary(run_length(64),heuristic(use_first(halving,approximation))))": 270,
"opt(dictionary(run_length(64),heuristic(use_first(halving,delta_largest))))": 277,
"opt(dictionary(sliding_window(128),continued_fractions(binary)))": 326,
"opt(dictionary(sliding_window(128),continued_fractions(co_binary)))": 326,
"opt(dictionary(sliding_window(128),continued_fractions(dichotomic)))": 306,
"opt(dictionary(sliding_window(128),heuristic(use_first(halving,approximation))))": 276,
"opt(dictionary(sliding_window(128),heuristic(use_first(halving,delta_largest))))": 348,
"opt(dictionary(sliding_window(16),continued_fractions(binary)))": 279,
"opt(dictionary(sliding_window(16),continued_fractions(co_binary)))": 279,
"opt(dictionary(sliding_window(16),continued_fractions(dichotomic)))": 279,
"opt(dictionary(sliding_window(16),heuristic(use_first(halving,approximation))))": 279,
"opt(dictionary(sliding_window(16),heuristic(use_first(halving,delta_largest))))": 279,
"opt(dictionary(sliding_window(32),continued_fractions(binary)))": 276,
"opt(dictionary(sliding_window(32),continued_fractions(co_binary)))": 276,
"opt(dictionary(sliding_window(32),continued_fractions(dichotomic)))": 275,
"opt(dictionary(sliding_window(32),heuristic(use_first(halving,approximation))))": 278,
"opt(dictionary(sliding_window(32),heuristic(use_first(halving,delta_largest))))": 289,
"opt(dictionary(sliding_window(4),continued_fractions(binary)))": 320,
"opt(dictionary(sliding_window(4),continued_fractions(co_binary)))": 320,
"opt(dictionary(sliding_window(4),continued_fractions(dichotomic)))": 320,
"opt(dictionary(sliding_window(4),heuristic(use_first(halving,approximation))))": 320,
"opt(dictionary(sliding_window(4),heuristic(use_first(halving,delta_largest))))": 320,
"opt(dictionary(sliding_window(64),continued_fractions(binary)))": 298,
"opt(dictionary(sliding_window(64),continued_fractions(co_binary)))": 298,
"opt(dictionary(sliding_window(64),continued_fractions(dichotomic)))": 284,
"opt(dictionary(sliding_window(64),heuristic(use_first(halving,approximation))))": 274,
"opt(dictionary(sliding_window(64),heuristic(use_first(halving,delta_largest))))": 284,
"opt(dictionary(sliding_window(8),continued_fractions(binary)))": 292,
"opt(dictionary(sliding_window(8),continued_fractions(co_binary)))": 292,
"opt(dictionary(sliding_window(8),continued_fractions(dichotomic)))": 292,
"opt(dictionary(sliding_window(8),heuristic(use_first(halving,approximation))))": 292,
"opt(dictionary(sliding_window(8),heuristic(use_first(halving,delta_largest))))": 292,
"opt(runs(continued_fractions(binary)))": 270,
"opt(runs(continued_fractions(co_binary)))": 270,
"opt(runs(continued_fractions(dichotomic)))": 270,
"opt(runs(heuristic(use_first(halving,approximation))))": 270,
"opt(runs(heuristic(use_first(halving,delta_largest))))": 269
} addchain-0.4.0/alg/ensemble/testdata/secp256k1_scalar.golden 0000664 0000000 0000000 00000035321 15143052566 0023571 0 ustar 00root root 0000000 0000000 {
"opt(dictionary(hybrid(2,0),continued_fractions(binary)))": 309,
"opt(dictionary(hybrid(2,0),continued_fractions(co_binary)))": 309,
"opt(dictionary(hybrid(2,0),continued_fractions(dichotomic)))": 301,
"opt(dictionary(hybrid(2,0),heuristic(use_first(halving,approximation))))": 309,
"opt(dictionary(hybrid(2,0),heuristic(use_first(halving,delta_largest))))": 406,
"opt(dictionary(hybrid(2,16),continued_fractions(binary)))": 303,
"opt(dictionary(hybrid(2,16),continued_fractions(co_binary)))": 303,
"opt(dictionary(hybrid(2,16),continued_fractions(dichotomic)))": 303,
"opt(dictionary(hybrid(2,16),heuristic(use_first(halving,approximation))))": 303,
"opt(dictionary(hybrid(2,16),heuristic(use_first(halving,delta_largest))))": 303,
"opt(dictionary(hybrid(2,32),continued_fractions(binary)))": 301,
"opt(dictionary(hybrid(2,32),continued_fractions(co_binary)))": 301,
"opt(dictionary(hybrid(2,32),continued_fractions(dichotomic)))": 301,
"opt(dictionary(hybrid(2,32),heuristic(use_first(halving,approximation))))": 301,
"opt(dictionary(hybrid(2,32),heuristic(use_first(halving,delta_largest))))": 314,
"opt(dictionary(hybrid(2,64),continued_fractions(binary)))": 303,
"opt(dictionary(hybrid(2,64),continued_fractions(co_binary)))": 303,
"opt(dictionary(hybrid(2,64),continued_fractions(dichotomic)))": 301,
"opt(dictionary(hybrid(2,64),heuristic(use_first(halving,approximation))))": 303,
"opt(dictionary(hybrid(2,64),heuristic(use_first(halving,delta_largest))))": 344,
"opt(dictionary(hybrid(3,0),continued_fractions(binary)))": 306,
"opt(dictionary(hybrid(3,0),continued_fractions(co_binary)))": 306,
"opt(dictionary(hybrid(3,0),continued_fractions(dichotomic)))": 298,
"opt(dictionary(hybrid(3,0),heuristic(use_first(halving,approximation))))": 306,
"opt(dictionary(hybrid(3,0),heuristic(use_first(halving,delta_largest))))": 403,
"opt(dictionary(hybrid(3,16),continued_fractions(binary)))": 300,
"opt(dictionary(hybrid(3,16),continued_fractions(co_binary)))": 300,
"opt(dictionary(hybrid(3,16),continued_fractions(dichotomic)))": 300,
"opt(dictionary(hybrid(3,16),heuristic(use_first(halving,approximation))))": 300,
"opt(dictionary(hybrid(3,16),heuristic(use_first(halving,delta_largest))))": 300,
"opt(dictionary(hybrid(3,32),continued_fractions(binary)))": 298,
"opt(dictionary(hybrid(3,32),continued_fractions(co_binary)))": 298,
"opt(dictionary(hybrid(3,32),continued_fractions(dichotomic)))": 298,
"opt(dictionary(hybrid(3,32),heuristic(use_first(halving,approximation))))": 298,
"opt(dictionary(hybrid(3,32),heuristic(use_first(halving,delta_largest))))": 311,
"opt(dictionary(hybrid(3,64),continued_fractions(binary)))": 300,
"opt(dictionary(hybrid(3,64),continued_fractions(co_binary)))": 300,
"opt(dictionary(hybrid(3,64),continued_fractions(dichotomic)))": 298,
"opt(dictionary(hybrid(3,64),heuristic(use_first(halving,approximation))))": 300,
"opt(dictionary(hybrid(3,64),heuristic(use_first(halving,delta_largest))))": 341,
"opt(dictionary(hybrid(4,0),continued_fractions(binary)))": 301,
"opt(dictionary(hybrid(4,0),continued_fractions(co_binary)))": 301,
"opt(dictionary(hybrid(4,0),continued_fractions(dichotomic)))": 293,
"opt(dictionary(hybrid(4,0),heuristic(use_first(halving,approximation))))": 302,
"opt(dictionary(hybrid(4,0),heuristic(use_first(halving,delta_largest))))": 399,
"opt(dictionary(hybrid(4,16),continued_fractions(binary)))": 295,
"opt(dictionary(hybrid(4,16),continued_fractions(co_binary)))": 295,
"opt(dictionary(hybrid(4,16),continued_fractions(dichotomic)))": 295,
"opt(dictionary(hybrid(4,16),heuristic(use_first(halving,approximation))))": 296,
"opt(dictionary(hybrid(4,16),heuristic(use_first(halving,delta_largest))))": 296,
"opt(dictionary(hybrid(4,32),continued_fractions(binary)))": 293,
"opt(dictionary(hybrid(4,32),continued_fractions(co_binary)))": 293,
"opt(dictionary(hybrid(4,32),continued_fractions(dichotomic)))": 293,
"opt(dictionary(hybrid(4,32),heuristic(use_first(halving,approximation))))": 294,
"opt(dictionary(hybrid(4,32),heuristic(use_first(halving,delta_largest))))": 307,
"opt(dictionary(hybrid(4,64),continued_fractions(binary)))": 295,
"opt(dictionary(hybrid(4,64),continued_fractions(co_binary)))": 295,
"opt(dictionary(hybrid(4,64),continued_fractions(dichotomic)))": 293,
"opt(dictionary(hybrid(4,64),heuristic(use_first(halving,approximation))))": 296,
"opt(dictionary(hybrid(4,64),heuristic(use_first(halving,delta_largest))))": 337,
"opt(dictionary(hybrid(5,0),continued_fractions(binary)))": 304,
"opt(dictionary(hybrid(5,0),continued_fractions(co_binary)))": 304,
"opt(dictionary(hybrid(5,0),continued_fractions(dichotomic)))": 296,
"opt(dictionary(hybrid(5,0),heuristic(use_first(halving,approximation))))": 305,
"opt(dictionary(hybrid(5,0),heuristic(use_first(halving,delta_largest))))": 402,
"opt(dictionary(hybrid(5,16),continued_fractions(binary)))": 298,
"opt(dictionary(hybrid(5,16),continued_fractions(co_binary)))": 298,
"opt(dictionary(hybrid(5,16),continued_fractions(dichotomic)))": 298,
"opt(dictionary(hybrid(5,16),heuristic(use_first(halving,approximation))))": 299,
"opt(dictionary(hybrid(5,16),heuristic(use_first(halving,delta_largest))))": 299,
"opt(dictionary(hybrid(5,32),continued_fractions(binary)))": 296,
"opt(dictionary(hybrid(5,32),continued_fractions(co_binary)))": 296,
"opt(dictionary(hybrid(5,32),continued_fractions(dichotomic)))": 296,
"opt(dictionary(hybrid(5,32),heuristic(use_first(halving,approximation))))": 297,
"opt(dictionary(hybrid(5,32),heuristic(use_first(halving,delta_largest))))": 310,
"opt(dictionary(hybrid(5,64),continued_fractions(binary)))": 298,
"opt(dictionary(hybrid(5,64),continued_fractions(co_binary)))": 298,
"opt(dictionary(hybrid(5,64),continued_fractions(dichotomic)))": 296,
"opt(dictionary(hybrid(5,64),heuristic(use_first(halving,approximation))))": 299,
"opt(dictionary(hybrid(5,64),heuristic(use_first(halving,delta_largest))))": 340,
"opt(dictionary(hybrid(6,0),continued_fractions(binary)))": 305,
"opt(dictionary(hybrid(6,0),continued_fractions(co_binary)))": 305,
"opt(dictionary(hybrid(6,0),continued_fractions(dichotomic)))": 297,
"opt(dictionary(hybrid(6,0),heuristic(use_first(halving,approximation))))": 307,
"opt(dictionary(hybrid(6,0),heuristic(use_first(halving,delta_largest))))": 403,
"opt(dictionary(hybrid(6,16),continued_fractions(binary)))": 299,
"opt(dictionary(hybrid(6,16),continued_fractions(co_binary)))": 299,
"opt(dictionary(hybrid(6,16),continued_fractions(dichotomic)))": 299,
"opt(dictionary(hybrid(6,16),heuristic(use_first(halving,approximation))))": 301,
"opt(dictionary(hybrid(6,16),heuristic(use_first(halving,delta_largest))))": 300,
"opt(dictionary(hybrid(6,32),continued_fractions(binary)))": 297,
"opt(dictionary(hybrid(6,32),continued_fractions(co_binary)))": 297,
"opt(dictionary(hybrid(6,32),continued_fractions(dichotomic)))": 297,
"opt(dictionary(hybrid(6,32),heuristic(use_first(halving,approximation))))": 299,
"opt(dictionary(hybrid(6,32),heuristic(use_first(halving,delta_largest))))": 311,
"opt(dictionary(hybrid(6,64),continued_fractions(binary)))": 299,
"opt(dictionary(hybrid(6,64),continued_fractions(co_binary)))": 299,
"opt(dictionary(hybrid(6,64),continued_fractions(dichotomic)))": 297,
"opt(dictionary(hybrid(6,64),heuristic(use_first(halving,approximation))))": 301,
"opt(dictionary(hybrid(6,64),heuristic(use_first(halving,delta_largest))))": 341,
"opt(dictionary(hybrid(7,0),continued_fractions(binary)))": 302,
"opt(dictionary(hybrid(7,0),continued_fractions(co_binary)))": 302,
"opt(dictionary(hybrid(7,0),continued_fractions(dichotomic)))": 294,
"opt(dictionary(hybrid(7,0),heuristic(use_first(halving,approximation))))": 303,
"opt(dictionary(hybrid(7,0),heuristic(use_first(halving,delta_largest))))": 399,
"opt(dictionary(hybrid(7,16),continued_fractions(binary)))": 296,
"opt(dictionary(hybrid(7,16),continued_fractions(co_binary)))": 296,
"opt(dictionary(hybrid(7,16),continued_fractions(dichotomic)))": 296,
"opt(dictionary(hybrid(7,16),heuristic(use_first(halving,approximation))))": 297,
"opt(dictionary(hybrid(7,16),heuristic(use_first(halving,delta_largest))))": 296,
"opt(dictionary(hybrid(7,32),continued_fractions(binary)))": 294,
"opt(dictionary(hybrid(7,32),continued_fractions(co_binary)))": 294,
"opt(dictionary(hybrid(7,32),continued_fractions(dichotomic)))": 294,
"opt(dictionary(hybrid(7,32),heuristic(use_first(halving,approximation))))": 295,
"opt(dictionary(hybrid(7,32),heuristic(use_first(halving,delta_largest))))": 307,
"opt(dictionary(hybrid(7,64),continued_fractions(binary)))": 296,
"opt(dictionary(hybrid(7,64),continued_fractions(co_binary)))": 296,
"opt(dictionary(hybrid(7,64),continued_fractions(dichotomic)))": 294,
"opt(dictionary(hybrid(7,64),heuristic(use_first(halving,approximation))))": 297,
"opt(dictionary(hybrid(7,64),heuristic(use_first(halving,delta_largest))))": 337,
"opt(dictionary(hybrid(8,0),continued_fractions(binary)))": 302,
"opt(dictionary(hybrid(8,0),continued_fractions(co_binary)))": 302,
"opt(dictionary(hybrid(8,0),continued_fractions(dichotomic)))": 294,
"opt(dictionary(hybrid(8,0),heuristic(use_first(halving,approximation))))": 304,
"opt(dictionary(hybrid(8,0),heuristic(use_first(halving,delta_largest))))": 400,
"opt(dictionary(hybrid(8,16),continued_fractions(binary)))": 296,
"opt(dictionary(hybrid(8,16),continued_fractions(co_binary)))": 296,
"opt(dictionary(hybrid(8,16),continued_fractions(dichotomic)))": 296,
"opt(dictionary(hybrid(8,16),heuristic(use_first(halving,approximation))))": 298,
"opt(dictionary(hybrid(8,16),heuristic(use_first(halving,delta_largest))))": 296,
"opt(dictionary(hybrid(8,32),continued_fractions(binary)))": 294,
"opt(dictionary(hybrid(8,32),continued_fractions(co_binary)))": 294,
"opt(dictionary(hybrid(8,32),continued_fractions(dichotomic)))": 294,
"opt(dictionary(hybrid(8,32),heuristic(use_first(halving,approximation))))": 296,
"opt(dictionary(hybrid(8,32),heuristic(use_first(halving,delta_largest))))": 308,
"opt(dictionary(hybrid(8,64),continued_fractions(binary)))": 296,
"opt(dictionary(hybrid(8,64),continued_fractions(co_binary)))": 296,
"opt(dictionary(hybrid(8,64),continued_fractions(dichotomic)))": 294,
"opt(dictionary(hybrid(8,64),heuristic(use_first(halving,approximation))))": 298,
"opt(dictionary(hybrid(8,64),heuristic(use_first(halving,delta_largest))))": 338,
"opt(dictionary(run_length(0),continued_fractions(binary)))": 309,
"opt(dictionary(run_length(0),continued_fractions(co_binary)))": 309,
"opt(dictionary(run_length(0),continued_fractions(dichotomic)))": 301,
"opt(dictionary(run_length(0),heuristic(use_first(halving,approximation))))": 309,
"opt(dictionary(run_length(0),heuristic(use_first(halving,delta_largest))))": 406,
"opt(dictionary(run_length(128),continued_fractions(binary)))": 309,
"opt(dictionary(run_length(128),continued_fractions(co_binary)))": 309,
"opt(dictionary(run_length(128),continued_fractions(dichotomic)))": 301,
"opt(dictionary(run_length(128),heuristic(use_first(halving,approximation))))": 309,
"opt(dictionary(run_length(128),heuristic(use_first(halving,delta_largest))))": 406,
"opt(dictionary(run_length(16),continued_fractions(binary)))": 303,
"opt(dictionary(run_length(16),continued_fractions(co_binary)))": 303,
"opt(dictionary(run_length(16),continued_fractions(dichotomic)))": 303,
"opt(dictionary(run_length(16),heuristic(use_first(halving,approximation))))": 303,
"opt(dictionary(run_length(16),heuristic(use_first(halving,delta_largest))))": 303,
"opt(dictionary(run_length(32),continued_fractions(binary)))": 301,
"opt(dictionary(run_length(32),continued_fractions(co_binary)))": 301,
"opt(dictionary(run_length(32),continued_fractions(dichotomic)))": 301,
"opt(dictionary(run_length(32),heuristic(use_first(halving,approximation))))": 301,
"opt(dictionary(run_length(32),heuristic(use_first(halving,delta_largest))))": 314,
"opt(dictionary(run_length(64),continued_fractions(binary)))": 303,
"opt(dictionary(run_length(64),continued_fractions(co_binary)))": 303,
"opt(dictionary(run_length(64),continued_fractions(dichotomic)))": 301,
"opt(dictionary(run_length(64),heuristic(use_first(halving,approximation))))": 303,
"opt(dictionary(run_length(64),heuristic(use_first(halving,delta_largest))))": 344,
"opt(dictionary(sliding_window(128),continued_fractions(binary)))": 330,
"opt(dictionary(sliding_window(128),continued_fractions(co_binary)))": 330,
"opt(dictionary(sliding_window(128),continued_fractions(dichotomic)))": 327,
"opt(dictionary(sliding_window(128),heuristic(use_first(halving,approximation))))": 328,
"opt(dictionary(sliding_window(128),heuristic(use_first(halving,delta_largest))))": 327,
"opt(dictionary(sliding_window(16),continued_fractions(binary)))": 303,
"opt(dictionary(sliding_window(16),continued_fractions(co_binary)))": 303,
"opt(dictionary(sliding_window(16),continued_fractions(dichotomic)))": 303,
"opt(dictionary(sliding_window(16),heuristic(use_first(halving,approximation))))": 304,
"opt(dictionary(sliding_window(16),heuristic(use_first(halving,delta_largest))))": 303,
"opt(dictionary(sliding_window(32),continued_fractions(binary)))": 301,
"opt(dictionary(sliding_window(32),continued_fractions(co_binary)))": 301,
"opt(dictionary(sliding_window(32),continued_fractions(dichotomic)))": 301,
"opt(dictionary(sliding_window(32),heuristic(use_first(halving,approximation))))": 312,
"opt(dictionary(sliding_window(32),heuristic(use_first(halving,delta_largest))))": 301,
"opt(dictionary(sliding_window(4),continued_fractions(binary)))": 317,
"opt(dictionary(sliding_window(4),continued_fractions(co_binary)))": 317,
"opt(dictionary(sliding_window(4),continued_fractions(dichotomic)))": 317,
"opt(dictionary(sliding_window(4),heuristic(use_first(halving,approximation))))": 317,
"opt(dictionary(sliding_window(4),heuristic(use_first(halving,delta_largest))))": 317,
"opt(dictionary(sliding_window(64),continued_fractions(binary)))": 311,
"opt(dictionary(sliding_window(64),continued_fractions(co_binary)))": 311,
"opt(dictionary(sliding_window(64),continued_fractions(dichotomic)))": 311,
"opt(dictionary(sliding_window(64),heuristic(use_first(halving,approximation))))": 310,
"opt(dictionary(sliding_window(64),heuristic(use_first(halving,delta_largest))))": 313,
"opt(dictionary(sliding_window(8),continued_fractions(binary)))": 302,
"opt(dictionary(sliding_window(8),continued_fractions(co_binary)))": 302,
"opt(dictionary(sliding_window(8),continued_fractions(dichotomic)))": 302,
"opt(dictionary(sliding_window(8),heuristic(use_first(halving,approximation))))": 304,
"opt(dictionary(sliding_window(8),heuristic(use_first(halving,delta_largest))))": 302,
"opt(runs(continued_fractions(binary)))": 301,
"opt(runs(continued_fractions(co_binary)))": 301,
"opt(runs(continued_fractions(dichotomic)))": 300,
"opt(runs(heuristic(use_first(halving,approximation))))": 299,
"opt(runs(heuristic(use_first(halving,delta_largest))))": 299
} addchain-0.4.0/alg/exec/ 0000775 0000000 0000000 00000000000 15143052566 0014744 5 ustar 00root root 0000000 0000000 addchain-0.4.0/alg/exec/example_test.go 0000664 0000000 0000000 00000001523 15143052566 0017766 0 ustar 00root root 0000000 0000000 package exec_test
import (
"fmt"
"log"
"math/big"
"github.com/mmcloughlin/addchain/alg/ensemble"
"github.com/mmcloughlin/addchain/alg/exec"
)
func Example() {
// Target number: 2²⁵⁵ - 21.
n := new(big.Int)
n.SetString("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeb", 16)
// Default ensemble of algorithms.
algorithms := ensemble.Ensemble()
// Use parallel executor.
ex := exec.NewParallel()
results := ex.Execute(n, algorithms)
// Output best result.
best := 0
for i, r := range results {
if r.Err != nil {
log.Fatal(r.Err)
}
if len(results[i].Program) < len(results[best].Program) {
best = i
}
}
r := results[best]
fmt.Printf("best: %d\n", len(r.Program))
fmt.Printf("algorithm: %s\n", r.Algorithm)
// Output:
// best: 266
// algorithm: opt(runs(continued_fractions(dichotomic)))
}
addchain-0.4.0/alg/exec/exec.go 0000664 0000000 0000000 00000003772 15143052566 0016230 0 ustar 00root root 0000000 0000000 // Package exec implements addition chain algorithm execution.
package exec
import (
"errors"
"io/ioutil"
"log"
"math/big"
"runtime"
"github.com/mmcloughlin/addchain"
"github.com/mmcloughlin/addchain/alg"
"github.com/mmcloughlin/addchain/internal/bigint"
)
// Result from applying an algorithm to a target.
type Result struct {
Target *big.Int
Algorithm alg.ChainAlgorithm
Err error
Chain addchain.Chain
Program addchain.Program
}
// Execute the algorithm on the target number n.
func Execute(n *big.Int, a alg.ChainAlgorithm) Result {
r := Result{
Target: n,
Algorithm: a,
}
r.Chain, r.Err = a.FindChain(n)
if r.Err != nil {
return r
}
// Note this also performs validation.
r.Program, r.Err = r.Chain.Program()
if r.Err != nil {
return r
}
// Still, verify that it produced what we wanted.
if !bigint.Equal(r.Chain.End(), n) {
r.Err = errors.New("did not produce the required value")
}
return r
}
// Parallel executes multiple algorithms in parallel.
type Parallel struct {
limit int
logger *log.Logger
}
// NewParallel builds a new parallel executor.
func NewParallel() *Parallel {
return &Parallel{
limit: runtime.NumCPU(),
logger: log.New(ioutil.Discard, "", 0),
}
}
// SetConcurrency sets the number of algorithms that may be run in parallel.
func (p *Parallel) SetConcurrency(limit int) {
p.limit = limit
}
// SetLogger sets logging output.
func (p *Parallel) SetLogger(l *log.Logger) {
p.logger = l
}
// Execute all algorithms against the provided target.
func (p Parallel) Execute(n *big.Int, as []alg.ChainAlgorithm) []Result {
rs := make([]Result, len(as))
// Use buffered channel to limit concurrency.
type token struct{}
sem := make(chan token, p.limit)
for i, a := range as {
sem <- token{}
go func(i int, a alg.ChainAlgorithm) {
p.logger.Printf("start: %s", a)
rs[i] = Execute(n, a)
p.logger.Printf("done: %s", a)
<-sem
}(i, a)
}
// Wait for completion.
for i := 0; i < p.limit; i++ {
sem <- token{}
}
return rs
}
addchain-0.4.0/alg/heuristic/ 0000775 0000000 0000000 00000000000 15143052566 0016017 5 ustar 00root root 0000000 0000000 addchain-0.4.0/alg/heuristic/heuristic.go 0000664 0000000 0000000 00000016521 15143052566 0020352 0 ustar 00root root 0000000 0000000 // Package heuristic implements heuristic-based addition sequence algorithms
// with the Bos-Coster Makesequence structure.
package heuristic
import (
"errors"
"fmt"
"math/big"
"strings"
"github.com/mmcloughlin/addchain"
"github.com/mmcloughlin/addchain/internal/bigint"
"github.com/mmcloughlin/addchain/internal/bigints"
)
// References:
//
// [boscoster] Bos, Jurjen and Coster, Matthijs. Addition Chain Heuristics. In Advances in
// Cryptology --- CRYPTO' 89 Proceedings, pages 400--407. 1990.
// https://link.springer.com/content/pdf/10.1007/0-387-34805-0_37.pdf
// [github:kwantam/addchain] Riad S. Wahby. kwantam/addchain. Github Repository. Apache License, Version 2.0.
// 2018. https://github.com/kwantam/addchain
// [hehcc:exp] Christophe Doche. Exponentiation. Handbook of Elliptic and Hyperelliptic Curve
// Cryptography, chapter 9. 2006.
// http://koclab.cs.ucsb.edu/teaching/ecc/eccPapers/Doche-ch09.pdf
// [modboscoster] Ayan Nandy. Modifications of Bos and Coster’s Heuristics in search of a
// shorter addition chain for faster exponentiation. Masters thesis, Indian
// Statistical Institute Kolkata. 2011.
// http://library.isical.ac.in:8080/jspui/bitstream/10263/6441/1/DISS-285.pdf
// [mpnt] F. L. Ţiplea, S. Iftene, C. Hriţcu, I. Goriac, R. Gordân and E. Erbiceanu.
// MpNT: A Multi-Precision Number Theory Package, Number Theoretical Algorithms
// (I). Technical Report TR03-02, Faculty of Computer Science, "Alexandru Ioan
// Cuza" University, Iasi. 2003. https://profs.info.uaic.ro/~tr/tr03-02.pdf
// [speedsubgroup] Stam, Martijn. Speeding up subgroup cryptosystems. PhD thesis, Technische
// Universiteit Eindhoven. 2003. https://cr.yp.to/bib/2003/stam-thesis.pdf
// Heuristic suggests insertions given a current protosequence.
type Heuristic interface {
// Suggest insertions given a target and protosequence f. Protosequence must
// contain sorted distinct integers.
Suggest(f []*big.Int, target *big.Int) []*big.Int
// String returns a name for the heuristic.
String() string
}
// Algorithm searches for an addition sequence using a heuristic at each step.
// This implements the framework given in [mpnt], page 63, with the heuristic
// playing the role of the "newnumbers" function.
type Algorithm struct {
heuristic Heuristic
}
// NewAlgorithm builds a heuristic algorithm.
func NewAlgorithm(h Heuristic) *Algorithm {
return &Algorithm{
heuristic: h,
}
}
func (h Algorithm) String() string {
return fmt.Sprintf("heuristic(%v)", h.heuristic)
}
// FindSequence searches for an addition sequence for the given targets.
func (h Algorithm) FindSequence(targets []*big.Int) (addchain.Chain, error) {
// Skip the special case when targets is just {1}.
if len(targets) == 1 && bigint.EqualInt64(targets[0], 1) {
return targets, nil
}
// Initialize protosequence.
leader := bigints.Int64s(1, 2)
proto := append(leader, targets...)
bigints.Sort(proto)
proto = bigints.Unique(proto)
c := []*big.Int{}
for len(proto) > 2 {
// Pop the target element.
top := len(proto) - 1
target := proto[top]
proto = proto[:top]
c = bigints.InsertSortedUnique(c, target)
// Apply heuristic.
insert := h.heuristic.Suggest(proto, target)
if insert == nil {
return nil, errors.New("failed to find sequence")
}
// Update protosequence.
proto = bigints.MergeUnique(proto, insert)
}
// Prepare the chain to return.
c = bigints.MergeUnique(leader, c)
return addchain.Chain(c), nil
}
// DeltaLargest implements the simple heuristic of adding the delta between the
// largest two entries in the protosequence.
type DeltaLargest struct{}
func (DeltaLargest) String() string { return "delta_largest" }
// Suggest proposes inserting target-max(f).
func (DeltaLargest) Suggest(f []*big.Int, target *big.Int) []*big.Int {
n := len(f)
delta := new(big.Int).Sub(target, f[n-1])
if delta.Sign() <= 0 {
panic("delta must be positive")
}
return []*big.Int{delta}
}
// Approximation is the "Approximation" heuristic from [boscoster].
type Approximation struct{}
func (Approximation) String() string { return "approximation" }
// Suggest applies the "Approximation" heuristic. This heuristic looks for two
// elements a, b in the list that sum to something close to the target element
// f. That is, we look for f-(a+b) = epsilon where a ⩽ b and epsilon is a
// "small" positive value.
func (Approximation) Suggest(f []*big.Int, target *big.Int) []*big.Int {
delta := new(big.Int)
insert := new(big.Int)
mindelta := new(big.Int)
best := new(big.Int)
first := true
// Leverage the fact that f contains sorted distinct integers to apply a
// linear algorithm, similar to the 2-SUM problem. Maintain left and right
// pointers and adjust them based on whether the sum is above or below the
// target.
for l, r := 0, len(f)-1; l <= r; {
a, b := f[l], f[r]
// Compute the delta f-(a+b).
delta.Add(a, b)
delta.Sub(target, delta)
if delta.Sign() < 0 {
// Sum exceeds target, decrement r for smaller b value.
r--
continue
}
// Proposed insertion is a+delta.
insert.Add(a, delta)
// If it's actually in the sequence already, use it.
if bigints.ContainsSorted(insert, f) {
return []*big.Int{insert}
}
// Keep it if its the closest we've seen.
if first || delta.Cmp(mindelta) < 0 {
mindelta.Set(delta)
best.Set(insert)
first = false
}
// Advance to next a value.
l++
}
return []*big.Int{best}
}
// Halving is the "Halving" heuristic from [boscoster].
type Halving struct{}
func (Halving) String() string { return "halving" }
// Suggest applies when the target is at least twice as big as the next largest.
// If so it will return a sequence of doublings to insert. Otherwise it will
// return nil.
func (Halving) Suggest(f []*big.Int, target *big.Int) []*big.Int {
n := len(f)
max, next := target, f[n-1]
// Check the condition f / f₁ ⩾ 2ᵘ
r := new(big.Int).Div(max, next)
if r.BitLen() < 2 {
return nil
}
u := r.BitLen() - 1
// Compute k = floor( f / 2ᵘ ).
k := new(big.Int).Rsh(max, uint(u))
// Proposal to insert:
// Delta d = f - k*2ᵘ
// Sequence k, 2*k, ..., k*2ᵘ
kshifts := []*big.Int{}
for e := 0; e <= u; e++ {
kshift := new(big.Int).Lsh(k, uint(e))
kshifts = append(kshifts, kshift)
}
d := new(big.Int).Sub(max, kshifts[u])
if bigint.IsZero(d) {
return kshifts[:u]
}
return bigints.InsertSortedUnique(kshifts, d)
}
// UseFirst builds a compositite heuristic that will make the first non-nil
// suggestion from the sub-heuristics.
func UseFirst(heuristics ...Heuristic) Heuristic {
return useFirst(heuristics)
}
type useFirst []Heuristic
func (h useFirst) String() string {
names := []string{}
for _, sub := range h {
names = append(names, sub.String())
}
return "use_first(" + strings.Join(names, ",") + ")"
}
// Suggest delegates to each sub-heuristic in turn and returns the first non-nil suggestion.
func (h useFirst) Suggest(f []*big.Int, target *big.Int) []*big.Int {
for _, heuristic := range h {
if insert := heuristic.Suggest(f, target); insert != nil {
return insert
}
}
return nil
}
addchain-0.4.0/alg/heuristic/heuristic_test.go 0000664 0000000 0000000 00000002554 15143052566 0021412 0 ustar 00root root 0000000 0000000 package heuristic
import (
"math/big"
"reflect"
"testing"
"github.com/mmcloughlin/addchain/alg/algtest"
"github.com/mmcloughlin/addchain/internal/bigints"
)
// References:
//
// [hehcc:exp] Christophe Doche. Exponentiation. Handbook of Elliptic and Hyperelliptic Curve
// Cryptography, chapter 9. 2006.
// http://koclab.cs.ucsb.edu/teaching/ecc/eccPapers/Doche-ch09.pdf
func TestAlgorithms(t *testing.T) {
heuristics := []Heuristic{
UseFirst(Halving{}, DeltaLargest{}),
UseFirst(Halving{}, Approximation{}),
}
for _, heuristic := range heuristics {
suite := algtest.SequenceAlgorithmSuite{
Algorithm: NewAlgorithm(heuristic),
AcceptsLargeInputs: true,
}
t.Run(suite.Algorithm.String(), suite.Tests())
}
}
func TestHalving(t *testing.T) {
cases := []struct {
F []*big.Int
Target *big.Int
Expect []*big.Int
}{
// Example from [hehcc:exp], page 163.
{
F: bigints.Int64s(14),
Target: big.NewInt(382),
Expect: bigints.Int64s(14, 23, 46, 92, 184, 368),
},
// Simple powers of two case.
{
F: bigints.Int64s(1, 2),
Target: big.NewInt(8),
Expect: bigints.Int64s(2, 4),
},
}
h := Halving{}
for _, c := range cases {
if got := h.Suggest(c.F, c.Target); !reflect.DeepEqual(c.Expect, got) {
t.Errorf("Suggest(%v, %v) = %v; expect %v", c.F, c.Target, got, c.Expect)
}
}
}
addchain-0.4.0/alg/opt/ 0000775 0000000 0000000 00000000000 15143052566 0014622 5 ustar 00root root 0000000 0000000 addchain-0.4.0/alg/opt/opt.go 0000664 0000000 0000000 00000004301 15143052566 0015751 0 ustar 00root root 0000000 0000000 // Package opt implements generic optimizations that remove redundancy from addition chains.
package opt
import (
"fmt"
"math/big"
"github.com/mmcloughlin/addchain"
"github.com/mmcloughlin/addchain/alg"
)
// Algorithm applies chain optimization to the result of a wrapped algorithm.
type Algorithm struct {
Algorithm alg.ChainAlgorithm
}
func (a Algorithm) String() string {
return fmt.Sprintf("opt(%s)", a.Algorithm)
}
// FindChain delegates to the wrapped algorithm, then runs Optimize on the result.
func (a Algorithm) FindChain(n *big.Int) (addchain.Chain, error) {
c, err := a.Algorithm.FindChain(n)
if err != nil {
return nil, err
}
opt, err := Optimize(c)
if err != nil {
return nil, err
}
return opt, nil
}
// Optimize aims to remove redundancy from an addition chain.
func Optimize(c addchain.Chain) (addchain.Chain, error) {
// Build program for c with all possible options at each step.
ops := make([][]addchain.Op, len(c))
for k := 1; k < len(c); k++ {
ops[k] = c.Ops(k)
}
// Count how many times each index is used where it is the only available Op.
counts := make([]int, len(c))
for k := 1; k < len(c); k++ {
if len(ops[k]) != 1 {
continue
}
for _, i := range ops[k][0].Operands() {
counts[i]++
}
}
// Now, try to remove the positions which are never the only available op.
remove := []int{}
for k := 1; k < len(c)-1; k++ {
if counts[k] > 0 {
continue
}
// Prune places k is used.
for l := k + 1; l < len(c); l++ {
ops[l] = pruneuses(ops[l], k)
// If this list now only has one element, the operands in it are now
// indispensable.
if len(ops[l]) == 1 {
for _, i := range ops[l][0].Operands() {
counts[i]++
}
}
}
// Mark k for deletion.
remove = append(remove, k)
}
// Perform removals.
pruned := addchain.Chain{}
for i, x := range c {
if len(remove) > 0 && remove[0] == i {
remove = remove[1:]
continue
}
pruned = append(pruned, x)
}
return pruned, nil
}
// pruneuses removes any uses of i from the list of operations.
func pruneuses(ops []addchain.Op, i int) []addchain.Op {
filtered := ops[:0]
for _, op := range ops {
if !op.Uses(i) {
filtered = append(filtered, op)
}
}
return filtered
}
addchain-0.4.0/alg/opt/opt_test.go 0000664 0000000 0000000 00000002356 15143052566 0017020 0 ustar 00root root 0000000 0000000 package opt
import (
"testing"
"github.com/mmcloughlin/addchain"
"github.com/mmcloughlin/addchain/internal/bigints"
)
func TestOptimize(t *testing.T) {
cases := []struct {
Input addchain.Chain
Expect addchain.Chain
}{
// Sub-optimal case. Should remove 3 or 4.
{
Input: bigints.Int64s(1, 2, 3, 4, 5),
Expect: bigints.Int64s(1, 2, 4, 5),
},
// Optimal case. Should do nothing.
{
Input: bigints.Int64s(1, 2, 4, 5),
Expect: bigints.Int64s(1, 2, 4, 5),
},
// Two removals are possible in this case.
{
Input: bigints.Int64s(1, 2, 3, 4, 6, 7, 8, 14, 20, 24),
Expect: bigints.Int64s(1, 2, 4, 6, 7, 14, 20, 24),
},
}
for _, c := range cases {
// Verify both are possible.
if err := c.Input.Validate(); err != nil {
t.Fatal(err)
}
if err := c.Expect.Validate(); err != nil {
t.Fatal(err)
}
// Run optimization.
got, err := Optimize(c.Input)
if err != nil {
t.Fatal(err)
}
// Require that the result is still valid, and at least as good as the expected.
if err := got.Produces(c.Input.End()); err != nil {
t.Fatal("optimization result does not end in the same value")
}
if len(c.Expect) < len(got) {
t.Fatalf("Optimize(%v) = %v; expect %v", c.Input, got, c.Expect)
}
}
}
addchain-0.4.0/chain.go 0000664 0000000 0000000 00000011110 15143052566 0014660 0 ustar 00root root 0000000 0000000 // Package addchain provides addition chain types and operations on them.
package addchain
import (
"errors"
"fmt"
"math/big"
"github.com/mmcloughlin/addchain/internal/bigint"
"github.com/mmcloughlin/addchain/internal/bigints"
)
// References:
//
// [efficientcompaddchain] Bergeron, F., Berstel, J. and Brlek, S. Efficient computation of addition
// chains. Journal de theorie des nombres de Bordeaux. 1994.
// http://www.numdam.org/item/JTNB_1994__6_1_21_0
// [knuth] Knuth, Donald E. Evaluation of Powers. The Art of Computer Programming, Volume 2
// (Third Edition): Seminumerical Algorithms, chapter 4.6.3. 1997.
// https://www-cs-faculty.stanford.edu/~knuth/taocp.html
// Chain is an addition chain.
type Chain []*big.Int
// New constructs the minimal chain {1}.
func New() Chain {
return Chain{big.NewInt(1)}
}
// Int64s builds a chain from the given int64 values.
func Int64s(xs ...int64) Chain {
return Chain(bigints.Int64s(xs...))
}
// Clone the chain.
func (c Chain) Clone() Chain {
return bigints.Clone(c)
}
// AppendClone appends a copy of x to c.
func (c *Chain) AppendClone(x *big.Int) {
*c = append(*c, bigint.Clone(x))
}
// End returns the last element of the chain.
func (c Chain) End() *big.Int {
return c[len(c)-1]
}
// Ops returns all operations that produce the kth position. This could be empty
// for an invalid chain.
func (c Chain) Ops(k int) []Op {
ops := []Op{}
s := new(big.Int)
// If the prefix is ascending this can be done in linear time.
if c[:k].IsAscending() {
for l, r := 0, k-1; l <= r; {
s.Add(c[l], c[r])
cmp := s.Cmp(c[k])
if cmp == 0 {
ops = append(ops, Op{l, r})
}
if cmp <= 0 {
l++
} else {
r--
}
}
return ops
}
// Fallback to quadratic.
for i := 0; i < k; i++ {
for j := i; j < k; j++ {
s.Add(c[i], c[j])
if s.Cmp(c[k]) == 0 {
ops = append(ops, Op{i, j})
}
}
}
return ops
}
// Op returns an Op that produces the kth position.
func (c Chain) Op(k int) (Op, error) {
ops := c.Ops(k)
if len(ops) == 0 {
return Op{}, fmt.Errorf("position %d is not the sum of previous entries", k)
}
return ops[0], nil
}
// Program produces a program that generates the chain.
func (c Chain) Program() (Program, error) {
// Sanity checks.
if len(c) == 0 {
return nil, errors.New("chain empty")
}
if c[0].Cmp(big.NewInt(1)) != 0 {
return nil, errors.New("chain must start with 1")
}
if bigints.Contains(bigint.Zero(), c) {
return nil, errors.New("chain contains zero")
}
for i := 0; i < len(c); i++ {
for j := i + 1; j < len(c); j++ {
if bigint.Equal(c[i], c[j]) {
return nil, fmt.Errorf("chain contains duplicate: %v at positions %d and %d", c[i], i, j)
}
}
}
// Produce the program.
p := Program{}
for k := 1; k < len(c); k++ {
op, err := c.Op(k)
if err != nil {
return nil, err
}
p = append(p, op)
}
return p, nil
}
// Validate checks that c is in fact an addition chain.
func (c Chain) Validate() error {
_, err := c.Program()
return err
}
// Produces checks that c is a valid chain ending with target.
func (c Chain) Produces(target *big.Int) error {
if err := c.Validate(); err != nil {
return err
}
if c.End().Cmp(target) != 0 {
return errors.New("chain does not end with target")
}
return nil
}
// Superset checks that c is a valid chain containing all the targets.
func (c Chain) Superset(targets []*big.Int) error {
if err := c.Validate(); err != nil {
return err
}
for _, target := range targets {
if !bigints.Contains(target, c) {
return fmt.Errorf("chain does not contain %v", target)
}
}
return nil
}
// IsAscending reports whether the chain is ascending, that is if it's in sorted
// order without repeats, as defined in [knuth] Section 4.6.3 formula (11).
// Does not fully validate the chain, only that it is ascending.
func (c Chain) IsAscending() bool {
if len(c) == 0 || !bigint.EqualInt64(c[0], 1) {
return false
}
for i := 1; i < len(c); i++ {
if c[i-1].Cmp(c[i]) >= 0 {
return false
}
}
return true
}
// Product computes the product of two addition chains. The is the "o times"
// operator defined in [efficientcompaddchain] Section 2.
func Product(a, b Chain) Chain {
c := a.Clone()
last := c.End()
for _, x := range b[1:] {
y := new(big.Int).Mul(last, x)
c = append(c, y)
}
return c
}
// Plus adds x to the addition chain. This is the "o plus" operator defined in
// [efficientcompaddchain] Section 2.
func Plus(a Chain, x *big.Int) Chain {
c := a.Clone()
y := new(big.Int).Add(c.End(), x)
return append(c, y)
}
addchain-0.4.0/chain_test.go 0000664 0000000 0000000 00000003722 15143052566 0015731 0 ustar 00root root 0000000 0000000 package addchain
import (
"reflect"
"testing"
)
func TestChainOps(t *testing.T) {
cases := []struct {
Name string
Chain Chain
Expect [][]Op
}{
{
Name: "short",
Chain: Int64s(1, 2),
Expect: [][]Op{
{{0, 0}}, // 2
},
},
{
Name: "multiple_choices",
Chain: Int64s(1, 2, 3, 4),
Expect: [][]Op{
{{0, 0}}, // 2
{{0, 1}}, // 3
{{0, 2}, {1, 1}}, // 4
},
},
{
Name: "non_ascending",
Chain: Int64s(1, 2, 3, 4, 7, 5, 6),
Expect: [][]Op{
{{0, 0}}, // 2
{{0, 1}}, // 3
{{0, 2}, {1, 1}}, // 4
{{2, 3}}, // 7
{{0, 3}, {1, 2}}, // 5
{{0, 5}, {1, 3}, {2, 2}}, // 6
},
},
}
for _, c := range cases {
c := c // scopelint
t.Run(c.Name, func(t *testing.T) {
var got [][]Op
for k := 1; k < len(c.Chain); k++ {
got = append(got, c.Chain.Ops(k))
}
if !reflect.DeepEqual(got, c.Expect) {
t.Logf("got = %v", got)
t.Logf("expect = %v", c.Expect)
t.Fail()
}
})
}
}
func TestChainIsAscending(t *testing.T) {
cases := []struct {
Name string
Chain Chain
Expect bool
}{
{Name: "empty", Chain: Int64s(), Expect: false},
{Name: "does_not_start_with_one", Chain: Int64s(42), Expect: false},
{Name: "ascending", Chain: Int64s(1, 2, 3, 5, 8), Expect: true},
{Name: "repeat", Chain: Int64s(1, 2, 3, 3, 8), Expect: false},
{Name: "not_sorted", Chain: Int64s(1, 2, 3, 4, 7, 5, 6), Expect: false},
}
for _, c := range cases {
c := c // scopelint
t.Run(c.Name, func(t *testing.T) {
if got := c.Chain.IsAscending(); got != c.Expect {
t.Fatalf("%v.IsAscending() = %v; expect %v", c.Chain, got, c.Expect)
}
})
}
}
func TestProduct(t *testing.T) {
a := Int64s(1, 2, 4, 6, 10)
b := Int64s(1, 2, 4, 8)
got := Product(a, b)
expect := Int64s(1, 2, 4, 6, 10, 20, 40, 80)
if !reflect.DeepEqual(expect, got) {
t.Fatalf("Product(%v, %v) = %v; expect %v", a, b, got, expect)
}
}
addchain-0.4.0/cmd/ 0000775 0000000 0000000 00000000000 15143052566 0014020 5 ustar 00root root 0000000 0000000 addchain-0.4.0/cmd/addchain/ 0000775 0000000 0000000 00000000000 15143052566 0015553 5 ustar 00root root 0000000 0000000 addchain-0.4.0/cmd/addchain/cite.go 0000664 0000000 0000000 00000001476 15143052566 0017036 0 ustar 00root root 0000000 0000000 package main
import (
"context"
"flag"
"os"
"github.com/google/subcommands"
"github.com/mmcloughlin/addchain/internal/cli"
"github.com/mmcloughlin/addchain/meta"
)
// cite subcommand.
type cite struct {
properties *meta.Properties
cli.Command
}
func (*cite) Name() string { return "cite" }
func (*cite) Synopsis() string { return "output addchain citation" }
func (*cite) Usage() string {
return `Usage: cite
Output citation for addchain.
`
}
func (cmd *cite) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) (status subcommands.ExitStatus) {
// Check citable.
if err := cmd.properties.CheckCitable(); err != nil {
return cmd.Error(err)
}
// Generate citation.
if err := cmd.properties.WriteCitation(os.Stdout); err != nil {
return cmd.Error(err)
}
return subcommands.ExitSuccess
}
addchain-0.4.0/cmd/addchain/eval.go 0000664 0000000 0000000 00000002543 15143052566 0017035 0 ustar 00root root 0000000 0000000 package main
import (
"context"
"flag"
"fmt"
"github.com/google/subcommands"
"github.com/mmcloughlin/addchain/acc"
"github.com/mmcloughlin/addchain/acc/parse"
"github.com/mmcloughlin/addchain/acc/pass"
"github.com/mmcloughlin/addchain/internal/cli"
)
// eval subcommand.
type eval struct {
cli.Command
}
func (*eval) Name() string { return "eval" }
func (*eval) Synopsis() string { return "evaluate an addition chain script" }
func (*eval) Usage() string {
return `Usage: eval [z = 2n*x
Under the hood, `addchain` has processed the addition chain into the [`ir.Program`](https://pkg.go.dev/github.com/mmcloughlin/addchain/acc/ir#Program) intermediate representation and used an allocation
pass to assign the minimum number of temporary variables. The listing format is
intended be a convient and easy-to-parse text format to use as input to other
tools.
In addition, `addchain` also offers templated output. In fact, the
listing is actually produced by the [listing](#listing) builtin template. See
below for details of the [templating language](#template-reference)
and [builtin template examples](#builtin-templates). The following template
can be used to directly produce Go code to execute the inversion chain:
```
// Code generated by {{ .Meta.Name }}. DO NOT EDIT.
package fp25519
// Inv computes z = 1/x (mod p) and returns it.
func (z *Elt) Inv(x *Elt) *Elt {
// Inversion computation is derived from the addition chain:
//
{{- range lines (format .Script) }}
// {{ . }}
{{- end }}
//
// Operations: {{ .Ops.Doubles }} squares {{ .Ops.Adds }} multiplies
//
// Generated by {{ .Meta.Module }} {{ .Meta.ReleaseTag }}.
// Allocate Temporaries.
var (
{{- range .Program.Temporaries }}
{{ . }} = new(Elt)
{{- end -}}
)
{{ range $i := .Program.Instructions }}
// {{ printf "Step %d: %s = x^%#x" $i.Output.Index $i.Output (index $.Chain $i.Output.Index) }}
{{- with add $i.Op }}
{{ $i.Output }}.Mul({{ .X }}, {{ .Y }})
{{ end -}}
{{- with double $i.Op }}
{{ $i.Output }}.Sqr({{ .X }})
{{ end -}}
{{- with shift $i.Op -}}
{{- $first := 0 -}}
{{- if ne $i.Output.Identifier .X.Identifier }}
{{ $i.Output }}.Sqr({{ .X }})
{{- $first = 1 -}}
{{- end }}
for s := {{ $first }}; s < {{ .S }}; s++ {
{{ $i.Output }}.Sqr({{ $i.Output }})
}
{{ end -}}
{{- end }}
return z
}
```
Generate code by passing the template to `addchain`:
```sh
addchain gen -tmpl inv.tmpl inv.acc | gofmt > inv.go
```
The end product:
```go
// Code generated by addchain. DO NOT EDIT.
package fp25519
// Inv computes z = 1/x (mod p) and returns it.
func (z *Elt) Inv(x *Elt) *Elt {
// Inversion computation is derived from the addition chain:
//
// _10 = 2*1
// _11 = 1 + _10
// _1100 = _11 << 2
// _1111 = _11 + _1100
// _11110000 = _1111 << 4
// _11111111 = _1111 + _11110000
// x10 = _11111111 << 2 + _11
// x20 = x10 << 10 + x10
// x30 = x20 << 10 + x10
// x60 = x30 << 30 + x30
// x120 = x60 << 60 + x60
// x240 = x120 << 120 + x120
// x250 = x240 << 10 + x10
// return (x250 << 2 + 1) << 3 + _11
//
// Operations: 254 squares 12 multiplies
//
// Generated by github.com/mmcloughlin/addchain v0.4.0.
// Allocate Temporaries.
var (
t0 = new(Elt)
t1 = new(Elt)
t2 = new(Elt)
)
// Step 1: z = x^0x2
z.Sqr(x)
// Step 2: z = x^0x3
z.Mul(x, z)
// Step 4: t0 = x^0xc
t0.Sqr(z)
for s := 1; s < 2; s++ {
t0.Sqr(t0)
}
// Step 5: t0 = x^0xf
t0.Mul(z, t0)
// Step 9: t1 = x^0xf0
t1.Sqr(t0)
for s := 1; s < 4; s++ {
t1.Sqr(t1)
}
// Step 10: t0 = x^0xff
t0.Mul(t0, t1)
// Step 12: t0 = x^0x3fc
for s := 0; s < 2; s++ {
t0.Sqr(t0)
}
// Step 13: t0 = x^0x3ff
t0.Mul(z, t0)
// Step 23: t1 = x^0xffc00
t1.Sqr(t0)
for s := 1; s < 10; s++ {
t1.Sqr(t1)
}
// Step 24: t1 = x^0xfffff
t1.Mul(t0, t1)
// Step 34: t1 = x^0x3ffffc00
for s := 0; s < 10; s++ {
t1.Sqr(t1)
}
// Step 35: t1 = x^0x3fffffff
t1.Mul(t0, t1)
// Step 65: t2 = x^0xfffffffc0000000
t2.Sqr(t1)
for s := 1; s < 30; s++ {
t2.Sqr(t2)
}
// Step 66: t1 = x^0xfffffffffffffff
t1.Mul(t1, t2)
// Step 126: t2 = x^0xfffffffffffffff000000000000000
t2.Sqr(t1)
for s := 1; s < 60; s++ {
t2.Sqr(t2)
}
// Step 127: t1 = x^0xffffffffffffffffffffffffffffff
t1.Mul(t1, t2)
// Step 247: t2 = x^0xffffffffffffffffffffffffffffff000000000000000000000000000000
t2.Sqr(t1)
for s := 1; s < 120; s++ {
t2.Sqr(t2)
}
// Step 248: t1 = x^0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
t1.Mul(t1, t2)
// Step 258: t1 = x^0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00
for s := 0; s < 10; s++ {
t1.Sqr(t1)
}
// Step 259: t0 = x^0x3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
t0.Mul(t0, t1)
// Step 261: t0 = x^0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc
for s := 0; s < 2; s++ {
t0.Sqr(t0)
}
// Step 262: t0 = x^0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd
t0.Mul(x, t0)
// Step 265: t0 = x^0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe8
for s := 0; s < 3; s++ {
t0.Sqr(t0)
}
// Step 266: z = x^0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeb
z.Mul(z, t0)
return z
}
```
This code is part of a [full working example](../internal/examples/fp25519) that passes tests.
## Template Reference
Templates use Go [`text/template`](https://pkg.go.dev/text/template) syntax. The data structure passed
to the template is:
```go
type Data struct {
// Chain is the addition chain as a list of integers.
Chain addchain.Chain
// Ops is the complete sequence of addition operations required to compute
// the addition chain.
Ops addchain.Program
// Script is the condensed representation of the addition chain computation
// in the "addition chain calculator" language.
Script *ast.Chain
// Program is the intermediate representation of the addition chain
// computation. This representation is likely the most convenient for code
// generation. It contains a sequence of add, double and shift (repeated
// doubling) instructions required to compute the chain. Temporary variable
// allocation has been performed and the list of required temporaries
// populated.
Program *ir.Program
// Metadata about the addchain project and the specific release parameters.
// Please use this to include a reference or citation back to the addchain
// project in your generated output.
Meta *meta.Properties
}
```
In addition to the [builtin functions](https://pkg.go.dev/text/template#hdr-Functions),
templates may use:
| Name | Signature | Description |
| ---- | --------- | ----------- |
| **`add`** | `func(ir.Op) ir.Op` | If the input operation is an `ir.Add` then return it, otherwise return `nil` |
| **`double`** | `func(ir.Op) ir.Op` | If the input operation is an `ir.Double` then return it, otherwise return `nil` |
| **`shift`** | `func(ir.Op) ir.Op` | If the input operation is an `ir.Shift` then return it, otherwise return `nil` |
| **`inc`** | `func(int) int` | Increment an integer |
| **`format`** | `func(interface {}) (string, error)` | Formats an addition chain script (`*ast.Chain`) as a string |
| **`split`** | `func(string, string) []string` | Calls `strings.Split` |
| **`join`** | `func([]string, string) string` | Calls `strings.Join` |
| **`lines`** | `func(string) []string` | Split input string into lines |
## Builtin Templates
Example output for each builtin template is generated from the chain:
```
_10 = 2*1
_11 = 1 + _10
_1100 = _11 << 2
_1111 = _11 + _1100
_11110000 = _1111 << 4
_11111111 = _1111 + _11110000
x10 = _11111111 << 2 + _11
x20 = x10 << 10 + x10
x30 = x20 << 10 + x10
x60 = x30 << 30 + x30
x120 = x60 << 60 + x60
x240 = x120 << 120 + x120
x250 = x240 << 10 + x10
return (x250 << 2 + 1) << 3 + _11
```
### chain
```
{{- range $n, $value := .Chain -}}
{{- printf "%3d: %#x\n" (inc $n) $value -}}
{{- end -}}
```
chain templatelisting templateops templatescript template