Showing preview only (1,565K chars total). Download the full file or copy to clipboard to get everything.
Repository: classilla/cryanc
Branch: main
Commit: a1572fbfda3a
Files: 10
Total size: 1.5 MB
Directory structure:
gitextract_ym8tj97v/
├── .gitignore
├── CHANGELOG.md
├── README.md
├── carl.1
├── carl.c
├── carl.md
├── carl_mpw.sit.hqx
├── cryanc.c
├── cryanc.h
└── debughello
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
bak
bak/*
test
test/*
test.*
carl
mpw
mpw/*
================================================
FILE: CHANGELOG.md
================================================
# Changelog
## 2.2
- "Crypto Ancienne Meets the Hooded Fang"
- New ports to classic MacOS/MPW and AmigaOS, and contributed ports for SCO Unix 4.2 (SCO ODT) and SerenityOS.
- `carl` now can automatically fallback to TLS 1.2 contexts for sites that don't have ciphers in common with TLS 1.3 (except BeOS, which is always TLS 1.2 currently), along with a `-3` option to prevent fallback for testing and higher security. The `-2` option, conversely, forces TLS 1.2 and is intended for debugging only.
- Use `NO_FUNNY_ALIGNMENT` by default on SPARC, HP PA-RISC, MIPS and SuperH, which avoids crashes and performance-draining trips to the system alignment handler (Alpha on Tru64 still requires `-misalign`).
- Allow wrapped records in TLS 1.3 before changing ciphers.
- Support Fred Fish `egcs` on BeOS/PowerPC.
- Minor local and upstream fixes.
## 2.0
- Support for TLS 1.3 on all supported platforms except classic BeOS
(which still has support for TLS 1.2).
- ChaCha20Poly1305 now available on all big-endian architectures too.
- New official support for macOS on Apple silicon, with contributed support
for SCO OpenServer 6 on `i386`, Solaris 9 and 10 on SPARC v9, HP-UX 11.31
on Itanium, and HP-UX 10.20 and 11.11+ on PA-RISC.
- Multiple crash and early-termination bugs on classic BeOS wallpapered, at
least with Metrowerks `cc` on PowerPC hardware (see changed build
instructions).
- Support for RSA-PSS-RSAE-SHA-family signatures.
- Endian detection is now canonicalized and displayed at compile-time.
- Various upstream signature algorithm and verification fixes.
- Minimal `User-Agent` header added to `carl` on the command line to counter
`HTTP 500` errors from some nginx servers.
- Added a simple TLS hello packet debugger in Perl for development purposes.
## 1.5
- New official support for BeOS R5, Tru64 5.1B, SunOS 4.1 and IRIX 6.5,
with contributed support for the Mac OS X Public Beta, Cheetah and Puma,
NeXTSTEP 3.3 on 68K, Professional MachTen 2.3 on 68K, IRIX 6.5 with gcc
and Haiku R1.
- Fixed test failures on A/UX and Power MachTen.
- Compile-time options for reducing issues with unaligned pointers and
local variable size.
- Converts all comments to `/* */` for better compiler compatibility.
- Improves RFC 8422 compliance, fixing some server incompatibilities.
- Using secp521r1 due to issues with internal curve25519 implementation
(to be fixed).
- Adds `-N` option to `carl` and expands exit statuses.
## 1.0
- Initial release on Mac OS X 10.2+, Rhapsody/Mac OS Server, NeXTSTEP 3.3
on PA-RISC, macOS, Linux, NetBSD, A/UX 3.1, AIX 4+ and Power MachTen 4.1.4.
================================================
FILE: README.md
================================================
# Crypto Ancienne: TLS for the Internet of Old Things
Copyright (C) 2020-3 Cameron Kaiser and Contributors. All rights reserved.
Crypto Ancienne, or Cryanc for short, is a TLS library with an aim for compatibility with pre-C99 C compilers and geriatric architectures. The [TLS apocalypse](http://tenfourfox.blogspot.com/2018/02/the-tls-apocalypse-reaches-power-macs.html) may have knocked these hulking beasts out of the running for awhile, but now it's time for the Great Old Computing Ones to reclaim the Earth. That old server in your closet? It's only been sleeping, and now it's ready to take back the Web on the Web's own terms. 1997 just called and it's *ticked*.
Cryanc is intended as a *client* library. Although it can facilitate acting as a server, this is probably more efficiently and safely accomplished with a separate reverse proxy to which the encryption can be offloaded.
**The use of this library does not make your application cryptographically secure, and certain systems may entirely lack any technological means to make that possible. Its functionality and security should be regarded as, at best, "good enough to shoot yourself in the foot with."**
## Before you file an issue
- If you are filing an issue for a modern system, you should be using one of the upstream libraries, not this one. If you don't know what the upstreams are, you should read the next section before you do *anything else*.
- If you have not tested your issue against upstream, you should do that first. If it's an upstream bug, don't file it here.
- If you use this for something mission-critical, you are stupid. It may work, but you're still stupid.
- Issues without patches or PRs may or may not be addressed. Ever.
## Supported features
- TLS 1.3 with SNI (on most ports; based on [TLSe](https://github.com/eduardsui/tlse) with local improvements)
- Most standard crypto algorithms (from [`libtomcrypt`](https://github.com/libtom/libtomcrypt))
- Built-in PRNG (`arc4random` from OpenBSD, allegedly, they tell me), with facultative seeding from `/dev/urandom` if present
In addition, `carl`, the included `curl`-like utility and the Cryanc example application, also has:
- SOCKSv4 client support (keep your Old Ones behind a firewall, they tend to cause mental derangement in weaker humans)
- HTTP and HTTPS proxy feature with similarly ancient browsers that do not insist on using `CONNECT` (requires `inetd` or `inetd`-like connecting piece such as [`micro_inetd`](https://acme.com/software/micro_inetd/))
- Browsers known to work: NCSA X-Mosaic 2.7b\* and [Mosaic-CK](http://www.floodgap.com/retrotech/machten/mosaic/) on Un*xy things, Lynx and [MacLynx](http://www.floodgap.com/retrotech/mac/lynx/) 2.7 and possibly some early versions of 2.8, OmniWeb before 4.2, [Classilla 9.3.4b](http://www.floodgap.com/software/classilla/carl.html), [BeOS NetPositive+](https://oldvcr.blogspot.com/2022/10/going-where-beos-netpositive-hasnt-gone.html) (_not_ regular NetPositive), Magic Cap [Web Browser 3.5.1+](https://oldvcr.blogspot.com/2023/01/bringing-tls-to-magic-cap-datarover.html). Also see [this post](https://oldvcr.blogspot.com/2020/11/fun-with-crypto-ancienne-tls-for.html) and [this post](http://oldvcr.blogspot.com/2022/07/crypto-ancienne-20-now-brings-tls-13-to.html).
See the `carl` manual page in this repo for more (in `man` and Markdown format).
## Not yet supported but coming soon
**Don't file issues about these.** If you do, they will be closed as "user doesn't read documentation" and offenders will be ravenously eaten.
- No 0-RTT or session resumption.
- No ECDSA support. As a result, although certificate validation is available in the library, it is not presently enabled in `carl` as it can't yet validate ECDSA certificates.
These are all acknowledged limitations in TLSe and should improve as upstream does (or our time to work on it).
- Support for other, possibly better (C)PRNGs or the old `prngd`/`egd` protocol.
## Known differences
- kTLS is not presently enabled, even on systems that offer this support (define `WITH_KTLS` if you want it) and even though TLSe supports it: most platforms that need Crypto Ancienne won't have kTLS or a sufficiently new enough implementation and thus this will likely never be the default.
## Working configurations
These are tested using `carl`, which is the included example, and should "just work." Most configurations can build simply with `gcc -O3 -o carl carl.c`. The magic for operating system support is almost all in `cryanc.c`.
- Linux (`gcc`). This is tested on `ppc64le` but pretty much any architecture should be compatible (though see notes below about `NO_FUNNY_ALIGNMENT` if you are using a "classic" RISC CPU).
- NetBSD (`gcc`). Ditto with 32-bit PowerPC, 68K and little-endian MIPS, and probably works on most other BSDs. If someone wants to give this a whack on 4.4BSD or Ultrix I would be highly amused.
- Mach family (OpenSTEP 4.0 probably also works given that these all do):
- Mac OS X 10.2 through at least 12 (PowerPC, `i386`, `x86_64`, Apple silicon; Xcode `gcc` 3.3+ or `clang`)
- Mac OS X Server v1.2/Rhapsody 5.6 (PowerPC; `cc` (actually `gcc` 2.7.2.1))
- Tru64 5.1B (Alpha; `cc` (actually Compaq C V6.5)). Must compile with `-misalign`.
- NeXTSTEP 3.3 (HP PA-RISC; `cc` (actually `gcc` 2.5))
- Power MachTen 4.1.4 (PowerPC; `gcc` 2.8.1; `setstackspace 1048576 /usr/bin/cpp` and `setstackspace 4194304 /usr/bin/as`)
- AmigaOS 3.9 (68K; `gcc` 2.95.3 with `ixemul.library` and `ixnet.library`; `-mstackextend` strongly advised). Using library version 63.1; may work on earlier versions and earlier OSes. The [Aminet ADE package](http://aminet.net/package/dev/gcc/ADE) is most convenient for building this. Note that stack usage may be considerable -- my test script uses a stack of 132K minimum.
- IRIX 6.5.30 (SGI MIPS; `cc` (actually MIPSPro 7.4.4m)). For 6.5.22, you may need to use `c99` (older MIPSPro versions may also work with `c99`).
- AIX 4+ (PowerPC, Power ISA; `gcc` 2.7.2.2 and 4.8). This is tested on 4.1.5 and 6.1, and should "just work" on 5L and 7.
- A/UX 3.1 (68K; `gcc` 2.7.2.2, requires `-lbsd` or linking with `/lib/libbsd.a`)
- SunOS 4.1 (SPARC; `gcc` 2.95.2). Binary compatible with Solbourne OS/MP. Tested on OS/MP 4.1C (SunOS 4.1.3).
## Working contributed configurations
These are attested to be working but are maintained by others. Some "just work" and others have specific support in the code base.
- Mac OS X Public Beta through 10.1 (PowerPC; Apple `cc` 912+ (actually `gcc` 2.95.2))
- NeXTSTEP 3.3 (68K; `cc` (actually `gcc` 2.5))
- Professional MachTen 2.3 (68K; `gcc` 2.7.2.f.1)
- IRIX 6.5 (SGI MIPS; `gcc` 9.2.0)
- Haiku R1/beta2 (`x86_64`; `gcc` 8.3.0, requires `-lnetwork`)
- Solaris 9 and 10 (SPARC v9; `gcc` 2.95.3+, requires `-lsocket -lnsl`)
- SCO UNIX 4.2 OpenDesktop (SCO ODT) (`i386`; `gcc` 2.5.8+)
- OpenServer 6 (`i386`; `gcc` 7.3.0, requires `-lsocket`)
- HP-UX 11.31 (Itanium; `cc` A.06.26 and `gcc` 4.7.4)
- HP-UX 11.11+ (HP PA-RISC; `gcc` 4.7.1)
- HP-UX 10.20 (HP PA-RISC; `gcc` 2.95.3, requires `-Doldhpux`)
- SerenityOS (`x86_64`, `gcc` 12+ and `clang` 13+)
## Partially working configurations
These platforms do _not_ "just work." It is possible due to various compiler or OS limitations that they may never work completely.
- BeOS R5 (PowerPC BeBox and Power Macintosh; `cc` (actually Metrowerks CodeWarrior `mwcc` 2.2) or Fred Fish Geek Gadgets `gcc` 2.90.27 (`egcs-1.0.2`)). **This port is very fragile:**
- Must compile **without optimization** (i.e., `cc -o carl carl.c`, not even `-O`), and you may need to use `carl` with the `-t` option to disable timeouts or long transactions may not complete. For `gcc`, use something like ```
gcc -I`echo $BEINCLUDES | sed 's/;/ -I/g'` -o carl carl.c
```. However, CodeWarrior seems to produce a faster binary than `gcc` even though `gcc` can make a stable binary at `-O3`.
- TLS 1.3 is _not_ currently supported due to limited system resources; all requests are TLS 1.2.
- Due to differences in the way BeOS treats standard input, reading proxy requests from the TTY doesn't currently work (it does from files).
- Should work with `x86`; not tested with Dano, ZETA or BONE. These versions may not require these limitations. Submit your patch, you can help! (If you're using Haiku, you can just compile Cryanc normally.)
- Classic MacOS (PowerPC; MPW `MrC` 4.1.0f1c1 or better). This generates an MPW tool version of `carl` that runs within the MPW Shell or ToolServer. MacOS being MacOS, it has its own weir-dass build instructions:
- Install MPW and the [GUSI library distribution](https://sourceforge.net/projects/gusi/files/) if you haven't already, making sure you run the installation scripts or your setup won't have all the necessary headers. We use GUSI's latest version 2.2.3 but earlier versions may work. You also need to ensure that `${GUSI}` is set to your installation folder, which the installation should do for you (e.g., `Set -e "Macintosh HD:GUSI_223:"`).
- UnStuff `carl_mpw.sit.hqx`; you should get a folder named `mpw`. Open the `Makefile` inside it (it should start the MPW Shell) and ensure your working directory is that `mpw` folder, not the `cryanc` folder it's within.
- Press Command-B to build, and enter the target `carl`. The `Makefile` will fix up the type and creator of the source files and generate a tool `carl` in the same `mpw` folder.
- To run `carl` from the MPW Shell, just enter `carl` or `carl -options "URL"` (the URL must be quoted since slashes can be salient to MPW). `carl` will cooperatively multitask with MPW and other applications while running, even if a host does not respond (press Command-. to cancel a request). However, due to differences in the way the Shell treats standard input, reading proxy requests directly from the keyboard doesn't currently work (it does from files and pipes).
- **`MrC` generates verifiably incorrect code.** To reduce this risk, we disable optimization and spot-enable it only for certain critical or likely-safe functions. It is possible it has other bugs that cause miscompiles or crashes, or those functions aren't actually as safe as we think they are. Because most of the code is not optimized, you may need to use `carl` with the `-t` option to disable timeouts or long transactions may not complete.
- Because of high stack demands, if you experience crashes you may need to expand the MPW Shell's default stack allotment for tools. The `HEXA` 128 resource contains the default stack space as a 32-bit integer; a value of `0008 0000` would be 512K, for example.
- To use the `carl` MPW tool as a proxy requires a Mac `inetd` clone. The GUSI docs talk about "David Petersons `inetd`" [sic] but we can't find this (can you help?). We are exploring whether [ToolDaemon](https://github.com/fblondiau/ToolDaemon) can be hacked to serve this purpose, since the source code is available. In the meantime, if you need to run it as a proxy for Classilla or MacLynx, your best bet right now is to compile and run `carl` under Power MachTen -- and it will probably be more stable, too.
## Not tested or not working but might in the future
- Classic Mac OS (68K `SC` with GUSI; or PowerPC MPW `gcc` 2.5 with GUSI; or Metrowerks CodeWarrior on 68K or PowerPC with GUSI and SIOUX). The `gcc` MPW requires that the source files be converted to CR instead of CRLF and has other odd quirks, but should avoid `MrC`'s code generation problems. The same may apply for CodeWarrior. As for 68K Macs, the existing code may already work with Symantec C under MPW but I haven't tried, and unfortunately most 68K Macs will not be fast enough for many sites (see notes below about systems slower than 40MHz).
- It should be possible to port to Win32 with something like `mxe`; there are hooks for it in TLSe already.
- Solaris 2+ should work now that SunOS 4 does.
- HP-UX on 68K. We have one locally.
- Would be nice to eliminate the `ixemul` and `ixnet` dependencies for AmigaOS, but it was the easiest way of getting the port launched. Would also consider `libnix`-based code.
- The people demand a VMS port! Need to check the license for that C compiler on our VAXstation ...
## Porting it to your favourite geriatric platform
Most other platforms with `gcc` 2.5 or higher, support for 64-bit ints (usually `long long`) and `stdarg.h` should "just work."
If your system lacks `stdint.h`, you can try using `-DNOT_POSIX=1` to use the built-in definitions. You may also need to add `-include stdarg.h` and other headers. Consider compiling with `-DDEBUG` if you get crashes so you can see where it dies (it's also a neat way to see TLS under the hood).
A few architectures, especially old RISC, may not like the liberties taken with unaligned pointers and memory access. For these systems try `-DNO_FUNNY_ALIGNMENT`, which is the default for SPARC, HP PA-RISC, MIPS and SuperH. However, it seems we may not have smoked all of them out (for example, it's not good enough for DEC Alpha on Tru64, the king of alignment-finicky configurations, and we still have to use `-misalign` with the Compaq C compiler).
Large local stack allocations are occasionally used for buffering efficiency. If your compiler doesn't like this (Metrowerks comes to mind) or you get crashes when `carl` terminates, try `-DBIG_STRING_SIZE=xx`, substituting a smaller buffer size like 16384 or 4096.
Once you figure out the secret sauce, we encourage you to put some additional blocks into `cryanc.c` to get the right header files and compiler flags loaded. PRs accepted for these as long as no presently working configuration is regressed. Similarly, we would love to further expand our compiler support, though we now support quite a few.
Some systems may be too slow for present-day server expectations and thus will appear not to function even if the library otherwise works correctly. In our testing this starts to become a problem for CPUs slower than 40MHz or so, regardless of architecture. Even built with `-O3`, our little NetBSD Macintosh IIci with a 25MHz 68030 and no L2 card took 22 seconds
(give `carl` the `-t` option to disable timeouts) for a single short TLS 1.2 transaction to a local test server; a number of Internet hosts we tested it with simply cut the connection instead of waiting. Rude!
## Using it in your application
A simple `#include "cryanc.c"` is sufficient (add both `cryanc.c` and `cryanc.h` to your source code). `cryanc.h` serves to document the more or less public interface and can be used if you turn Cryanc into a library instead of simply merging it into your source.
`carl` demonstrates the basic notion:
- open a TCP socket
- `tls_create_context` creates the TLS context (`TLS_V12` or `TLS_V13`)
- `tls_sni_set` sets the SNI hostname for the context
- `tls_client_connect` initializes the connection
Your application then needs to service reads and writes. The loop at the end of `carl` is a complete example, using `select(3)` to determine when data has arrived, and using an additional interior read loop to satisfy some servers that demand the socket be serviced promptly.
As data accumulates from the TLS hello and calls to `tls_write`,
it should check `tls_get_write_buffer` and send this data down the socket. `carl` has a helper function called `https_send_pending` which it calls periodically to do this. Once the context write buffer is serviced, it clears the context buffer with `tls_buffer_clear`.
Likewise, as data is read from the socket, it is sent to `tls_consume_stream`. When the secure connection is established, `tls_established` will become true for the context and you can read data from `tls_read`.
If a TLS alert occurs, it can be fetched from `context->error_code`.
## Language pedantry note
Here, "crypto" is short for *la cryptographie* and therefore the use of the feminine singular *ancienne*, so there.
## Licenses and copyrights
Crypto Ancienne is released under the BSD license.
Copyright (C) 2020-3 Cameron Kaiser and Contributors. All rights reserved.
Based on TLSe. Copyright (C) 2016-2023 Eduard Suica. All rights reserved.
Based on Adam Langley's implementation of Curve25519. Copyright (C) 2008 Google, Inc. All rights reserved.
Based on OpenBSD's `arc4random` (allegedly). Copyright (C) 1996 David Mazieres. All rights reserved.
Based on `libtomcrypt` by Tom St Denis and contributors. Unlicense.
Based on public domain works by D. J. Bernstein.
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.
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.
================================================
FILE: carl.1
================================================
.TH carl 1 "Crypto Ancienne"
.SH NAME
carl \- Crypto Ancienne Resource Loader
.SH SYNOPSIS
.B carl
.RI [ options ]
\fIurl\fR
.SH DESCRIPTION
.B carl
is both a demonstration application for the Crypto Ancienne TLS library and a utility reminiscent of the much more comprehensive
.BR curl (1),
of which its name is a desperate pun. It may also be more suitable as a
.BR curl (1)
substitute for the older systems that Crypto Ancienne caters to, since
it has no prerequisites other than a compatible C compiler.
.LP
Like its inspiration,
.B carl
fetches URLs, emitting them to standard output. However,
.B carl
only supports HTTP and HTTPS (and only HTTP/0.9, HTTP/1.0 and HTTP/1.1), although it will also parse SOCKS URLs and use them as proxies (see
.BR ENVIRONMENT ).
.LP
.B carl
can also accept complete
HTTP and HTTPS requests over standard input (see
.B PROXY
.BR MODE ).
If connected to
.BR inetd (8)
or a similar utility, this can act as a complete proxy solution, including for some browsers which may not speak HTTPS or
current TLS versions themselves but can be trained or tricked to send requests for
.B https://
URLs to it.
.SH OPTIONS
In general, options do not match
.BR curl (1)'s.
.LP
.TP
.B \-q
Quiet mode; no verbose errors are displayed (see
.B EXIT
.BR STATUS ).
.TP
.B \-t
Disable timeouts. Otherwise, transactions that take longer than 10 seconds are aborted. Necessary for slower systems that may not negotiate TLS quickly enough. Given that Crypto Ancienne specifically caters to such systems, this option may become the default in future versions.
.TP
.B \-H
Use
.B HEAD
as the request method instead of
.BR GET .
In this mode, HTTP(S) headers are displayed automatically, along with any residual message body that may be transmitted by some servers. Other methods such as
.B POST
must be specified as proxy requests (i.e., sent over standard input when
.B \-p
is specified).
.TP
.B \-i
Dump both headers and body, even if
.B \-H
isn't specified. Irrelevant in proxy mode (when
.B \-p
is specified).
.TP
.B \-N
Ignore the
.B ALL_PROXY
environment variable, if it exists (see
.BR ENVIRONMENT ).
.TP
.B \-u
Treat all HTTP URLs as HTTPS, even if they are specified as HTTP. This includes URLs received in proxy mode (when
.B \-p
is specified).
.TP
.B \-s
Downgrade HTTP/1.1 replies to HTTP/1.0 for consumers or clients which are intolerant. Irrelevant if headers are not displayed (i.e., without
.BR \-H ,
.BR \-p
or
.BR \-i ).
.TP
.B \-2
Maximally negotiate TLS 1.2 instead of TLS 1.3. This is primarily for analysing handshake failures; under typical circumstances requiring this option to access a site should be considered a bug.
.TP
.B \-3
Conversely, do not allow fallbacks to a TLS 1.2 context if negotiating a TLS 1.3 context fails. By default
.B carl
will retry such connections to account for those hosts that genuinely support TLS 1.2 but not any of the ciphers that TLS 1.2 and TLS 1.3 would have in common. These sites are getting fewer and fewer, and thus this option may become the default in future versions.
.TP
.B \-p
Enables proxy mode (see
.B PROXY
.BR MODE ).
.BR \-i ,
.BR \-q ,
and
.BR \-H ,
if they are specified, are ignored. If a URL is provided, it may only be a
.B socks://
or
.B socks5://
URL, which is used as a SOCKS proxy for
.B carl
to relay through (see the
.B ALL_PROXY
environment variable in
.BR ENVIRONMENT ).
.TP
.B \-v
Display version string (the same as the main library).
.TP
.B \-h
Display a synopsis of these options.
.SH "PROXY MODE"
If the
.B \-p
option is specified,
.B carl
will accept a full proxy client request for an
.B http://
or
.B https://
URL from standard input. It must be formatted as a standard HTTP proxy request with method
and fully-specified URL minimally compliant to RFC 7230, though
.B carl
is tolerant, and will quietly adjust client requests as needed or requested (see also the
.B \-u
and
.B \-s
options). A full HTTP reply with all remote headers will be sent in response.
.LP
The request must be delimited by the standard two-CRLF separator. If the method is intended to send data to the server, such as
.BR POST ,
the payload may trail the request headers after it.
.B carl
does no encoding of this data; your application must do that itself.
.LP
In proxy mode, the \fIurl\fR argument may only be used to specify a SOCKS proxy through which the request will be forwarded. If the
.B ALL_PROXY
environment variable exists, specifying a SOCKS URL on the command line will override it (or use
.B -N
to ignore it; see
.BR ENVIRONMENT ).
Otherwise,
.B carl
will connect directly.
.LP
The
.B CONNECT
method is intentionally not implemented.
.LP
.B carl
does not bind any server port itself. However, because this mode accepts data on standard input, any
.BR inetd (8)
or
.BR inetd (8)-like
superserver environment such as
.BR xinetd (8)
or
.BR micro_inetd (1)
can be used to make it accessible on the network. \fICareful: if you bind an external interface, you've just made your computer into an open HTTP proxy!\fR
.B carl
implements no access controls or authentication, so check your superserver's documentation on how to only bind an internal interface or the loopback.
.SH ENVIRONMENT
.TP
.B ALL_PROXY
.B carl
has built-in SOCKSv4 client support. If a SOCKS URL (either
.B socks://
or
.BR socks5:// ,
which is treated as a synonym) is specified in this environment variable, all requests will be forwarded through it.
If a port number is not specified in the URL, it is assumed to be 1080. Any provided path or arguments are ignored.
.B carl
does not support authentication or SOCKSv5 features, and requires your DNS be able to resolve hostnames.
.IP
This variable is ignored if
.B \-N
is specified on the command line, and it is overridden in proxy mode
.RB ( \-p )
if a SOCKS URL is specified on the command line.
.LP
.B NO_PROXY
is not currently implemented.
.SH "EXIT STATUS"
A possibly helpful message may also appear unless it is suppressed by
.BR \-q .
These exit return codes may be expanded in future versions.
.TP
.B 0
No error.
.TP
.B 1
The request is pathological (nonsense, inappropriate or incomplete). This can also occur when a non-SOCKS proxy is provided
.RB ( carl
does not talk to other HTTP proxies; they are vapid and uninteresting at parties).
.TP
.B 2
The host or proxy host could not be resolved.
.TP
.B 3
The host resolved to an IPv6 address, but
.B carl
doesn't support those yet.
.TP
.B 4
The connection to the SOCKS proxy failed.
.TP
.B 5
The connection to the HTTP(S) server failed.
.TP
.B 6
The TLS response from the HTTPS server could not be processed.
.TP
.B 253
No data was received.
.TP
.B 254
Timeout. Consider using
.B \-t
if the system is slower and the request should have worked.
.TP
.B 255
General failure.
.SH NOTES
.B carl
does not currently evaluate certificates for validity, so its encryption support is best considered opportunistic and it
should not be used for high-security environments.
.SH "SEE ALSO"
.BR curl (1)
.SH "HOME PAGE"
https://github.com/classilla/cryanc
.SH AUTHOR
(C)2020-3 Cameron Kaiser and Contributors. All rights reserved. Additional copyrights apply; see the home page for full credits. BSD license.
================================================
FILE: carl.c
================================================
/*
* Crypto Ancienne Resource Loader "carl" (and example application)
* Copyright 2020-3 Cameron Kaiser and contributors. All rights reserved.
* BSD license (see README.md)
*/
#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#if defined (M_XENIX) && !defined(M_UNIX)
#include <sys/types.tcp.h>
#endif
#include <sys/socket.h>
#if !defined (M_XENIX) || defined(_SCO_DS) /* On SCO Unix the next line crashes gcc, but on OpenServer it might work/be needed? */
#if !defined(__AUX__) && !defined(__AMIGA__) && (!defined(NS_TARGET_MAJOR) || (NS_TARGET_MAJOR > 3)) && !defined(__MACHTEN_68K__) && !defined(__sun) && !defined(__BEOS__) && (!defined(__hppa) && !defined(__hpux)) && !defined(macintosh)
#include <sys/select.h>
#endif
#endif
#if defined(macintosh)
#include <ioctl.h>
#include <sys/filio.h>
#endif
#include <netinet/in.h>
#include <netdb.h>
#ifndef STDIN_FILENO
#define STDIN_FILENO 0
#endif
#ifndef STDOUT_FILENO
#define STDOUT_FILENO 1
#endif
/* stdint or equivalent set here */
#include "cryanc.c"
int quiet = 0;
int proxy = 0;
int http09 = 0;
void error(char *msg, int code) {
if (proxy) {
if (!http09)
fprintf(stdout, "HTTP/1.0 502 Proxy Error\r\n"
"Content-type: text/html\r\n\r\n");
fprintf(stdout, "%s\n", msg);
exit(code);
}
if (!quiet) {
if (errno > 0) perror(msg); else fprintf(stdout, "%s\n", msg);
}
exit(code);
}
void timeout() { /* portable enough */
error("Timeout", 254);
}
/* The BeOS port is bound by unusual constraints, partially by Metrowerks
cc, partially by the operating system. Some of the code here is
bizarre, but it's here because it works and passes tests. */
#if defined(__BEOS__)
#include <fcntl.h>
#if defined(BONE_VERSION)
#warning not tested with BONE
#endif
/* ping-pong interval for semi-busy wait */
#define TIMESLICE 1000
/* BeOS is "special" with stdin, and select() doesn't work with it. */
int stdin_pending() {
int i, j;
char c;
/* hack: don't check if we're not in proxy mode, we don't use it. */
if (!proxy) return 0;
/* check tty ioctl first */
i = ioctl(0, 'ichr', &j);
if (i >= 0 && j > 0) return 1;
/* "peek" at stdin (must already be non-blocking) */
return (read(STDIN_FILENO, &c, 0) >= 0);
}
#else
#if defined(macintosh)
/* The MacOS port is also bound by unusual constraints because it's MacOS. */
/* GUSI stdio isn't very std, so also check only in proxy mode. */
#define stdin_pending() (proxy && FD_ISSET(STDIN_FILENO, &fdset))
/* In a cooperative world connect() must be non-blocking. */
void mac_connect(int sockfd, struct sockaddr *s, int ssize, char *err, int code) {
long m=1;
fd_set fdset;
(void)ioctl(sockfd, FIONBIO, &m);
m = connect(sockfd, s, ssize);
if (m < 0) {
/* GUSI might return any of these values for an in-progress socket */
if (errno != EISCONN && /* connected already? */
errno != EINPROGRESS &&
errno != EALREADY)
error(err, code);
}
/* wait for it to become writeable. GUSI calls WaitNextEvent for us,
so make the socket blocking again to preserve other semantics. */
m=0; (void)ioctl(sockfd, FIONBIO, &m);
FD_ZERO(&fdset);
FD_SET(sockfd, &fdset);
(void)select(sockfd + 1, NULL, &fdset, NULL, NULL);
}
#else
#define stdin_pending() (FD_ISSET(STDIN_FILENO, &fdset))
#endif
#endif
int https_send_pending(int client_sock, struct TLSContext *context) {
unsigned int out_buffer_len = 0;
unsigned int out_buffer_index = 0;
int send_res = 0;
const unsigned char *out_buffer = tls_get_write_buffer(context, &out_buffer_len);
while ((out_buffer) && (out_buffer_len > 0)) {
int res = send(client_sock, (char *)&out_buffer[out_buffer_index], out_buffer_len, 0);
if (res <= 0) {
send_res = res;
break;
}
out_buffer_len -= res;
out_buffer_index += res;
}
tls_buffer_clear(context);
return send_res;
}
/* NYI */
int validate_certificate(struct TLSContext *context, struct TLSCertificate **certificate_chain, int len) {
int i;
if (certificate_chain) {
for (i = 0; i < len; i++) {
struct TLSCertificate *certificate = certificate_chain[i];
/* check certificate ... */
}
}
/* return certificate_expired;
// return certificate_revoked;
// return certificate_unknown; */
return no_error;
}
int scheme_is(char *url, char *scheme) {
if (strlen(url) <= strlen(scheme)) return 0;
return (strstr(url, scheme) == url);
}
/* given a URL string, set hostname, port and protocol (identified by well
known service port number) and return where in the string the path
starts (or NULL if it didn't parse correctly). */
char *parse_url(char *url, char *hostname, size_t *port, size_t *proto) {
char *h, *p, *pn;
unsigned int i;
if (scheme_is(url, "socks://")) {
*proto = 1080;
} else if (scheme_is(url, "socks5://")) {
*proto = 1080;
} else if (scheme_is(url, "http://")) {
*proto = 80;
} else if (scheme_is(url, "https://")) {
*proto = 443;
} else
return NULL; /* we don't know this protocol */
/* find the second slash: that's where the hostname starts. */
for (h=url,i=0;*h && i!=2;h++) if(*h=='/') i++;
if (i != 2) return NULL; /* ran off the end of the string */
/* find the third slash: that's where the selector starts. */
for (p=h;*p && i!=3;p++) if(*p=='/') i++;
/* if there is no third slash, treat as a zero-length path */
if (i == 3) p--;
/* hostname:port must be at least 1 character long. */
if ((p - h) < 1) return NULL;
if ((pn = strchr(h, ':')) && pn < p) {
/* automatic null termination */
char sport[6] = { 0, 0, 0, 0, 0, 0 };
/* check hostname and port lengths */
if (pn == h || (pn - h) > 255 || (p - pn) < 2 || (p - pn) > 6)
return NULL;
memcpy((void *)hostname, (void *)h, (pn - h));
*(hostname + (pn - h)) = '\0';
memcpy((void *)&sport, (void *)++pn, (p - pn));
*port = atoi(sport);
if (*port < 1 || *port > 65535) return NULL;
/* atoi will allow something like :3aa but we shouldn't */
if (*port < 10 && (p - pn) != 1) return NULL;
if (*port > 9 && *port < 100 && (p - pn) != 2) return NULL;
if (*port > 99 && *port < 1000 && (p - pn) != 3) return NULL;
if (*port > 999 && *port < 10000 && (p - pn) != 4) return NULL;
} else {
if ((p - h) > 255) return NULL;
memcpy((void *)hostname, (void *)h, (p - h));
*(hostname + (p - h)) = '\0';
*port = *proto;
}
/* we don't support authority information currently */
if (strchr(hostname, '@')) return NULL;
return p;
}
void help(int longdesc, char *me) {
fprintf(stderr, "Crypto Ancienne Resource Loader v2.2\n");
if (!longdesc) return;
fprintf(stderr,
"Copyright (C)2020-3 Cameron Kaiser and Contributors. All rights reserved.\n"
"usage: %s [option] [url (optional if -p)]\n\n"
"protocols: http https\n\n"
"-h This message\n"
"-v Version string\n"
"-p Proxy mode (accepts HTTP client request on stdin, ignores -i -q -H)\n"
" If url is also specified, it may be a socks:// URL only\n"
"-H HEAD request (default is GET)\n"
"-N Ignore ALL_PROXY environment variable\n"
"-q Emit no errors, only status code\n"
"-i Dump both headers and body (default is body only, irrelevant if -H or -p)\n"
"-t No timeout (default is 10s)\n"
"-u Upgrade HTTP requests to HTTPS transparently\n"
"-s Spoof HTTP/1.1 replies as HTTP/1.0 (irrelevant without -H, -p or -i)\n"
#if !defined(__BEOS__)
/* Accepted but ignored, being limited to TLS 1.2. */
"-3 Do not retry as TLS 1.2\n"
"-2 Negotiate TLS 1.2 instead of 1.3\n"
#endif
, me);
}
int main(int argc, char *argv[]) {
int sockfd, n, proxycon = 0, forever = 0, spoof10 = 0, stdindone = 0;
size_t portno, socksport, proto, socksproto, numcrs = 0, bytesread = 0;
struct sockaddr_in serv_addr;
struct hostent *server, *socksserver;
fd_set fdset;
int read_size, tls12 = 0, tls13only = 0;
int sent = 0, arg = 0, head_only = 0, with_headers = 0, upgrayedd = 0;
char *path = NULL, *url = NULL, *proxyurl = NULL;
struct TLSContext *context;
#if defined(__BEOS__)
struct timeval tv;
int i, j;
/* BeOS has a fixed stack of 256K, which makes this real tight. */
unsigned char client_message[1024];
unsigned char read_buffer[1024];
char hostname[64], sockshost[64], *buffer;
#else
char hostname[256], sockshost[256], *buffer;
unsigned char read_buffer[BIG_STRING_SIZE];
unsigned char client_message[8192];
#endif
proxyurl = getenv("ALL_PROXY");
if (proxyurl != NULL && !strlen(proxyurl)) proxyurl = NULL;
for(;;) {
if (++arg >= argc) {
if (proxy) break;
help(1, argv[0]);
return 1;
}
if (argv[arg][0] != '-') {
url = argv[arg];
break;
}
if (strchr(argv[arg], 'v')) { help(0, argv[0]); return 0; }
if (strchr(argv[arg], 'h')) { help(1, argv[0]); return 0; }
if (strchr(argv[arg], 'i')) { with_headers = 1; }
if (strchr(argv[arg], 'H')) { head_only = 1; with_headers = 1; }
if (strchr(argv[arg], 'N')) { proxyurl = NULL; }
if (strchr(argv[arg], '3')) { tls13only = 1; }
if (strchr(argv[arg], 'u')) { upgrayedd = 1; }
if (strchr(argv[arg], 's')) { spoof10 = 1; }
if (strchr(argv[arg], 't')) { forever = 1; }
if (strchr(argv[arg], 'q')) { quiet = 1; }
if (strchr(argv[arg], 'p')) { proxy = 1; }
if (strchr(argv[arg], '2')) { tls12 = 1; }
}
if (proxy) {
/* receiving a proxy request from stdin */
char method[10], purl[2048], c;
int mc = 0, mu = 0, got_method = 0, got_url = 0;
if (url) proxyurl = url;
head_only = 0; quiet = 1; with_headers = 0; http09 = 1;
method[0] = '\0'; purl[0] = '\0';
for(;;) {
if (!read(STDIN_FILENO, &c, 1))
return 1; /* something's wrong */
if (c == ' ') {
if (!got_method) { got_method = 1; continue; }
if (!got_url) { got_url = 1; http09 = 0; break; }
return 1; /* something's wrong here too */
}
if (c == '\r') {
if (!got_method) return 1;
if (got_url) return 1; /* ?! */
got_url = 1; continue;
}
if (c == '\n') {
if (got_method) break;
return 1; /* something's wrong here too */
}
if (!got_method) {
method[mc++] = (char)c; method[mc] = '\0';
if (mc == 9) return 1; /* bogus method */
continue;
}
if (!got_url) {
purl[mu++] = (char)c; purl[mu] = '\0';
if (mu == 2047) return 1; /* too long */
continue;
}
fprintf(stderr, "unhandled character: %c\n", (char)c);
return 255;
}
/* at this point, we either have a complete 0.9 request, or a 1.0/1.1
request with more bytes to follow. */
if (!strlen(method) || !strlen(purl)) return 1;
if (http09 && strcmp(method, "GET")) {
/* handle specially */
fprintf(stdout, "Only GET is supported for HTTP/0.9\n");
return 1;
}
if (!strcmp(method, "CONNECT")) {
error("CONNECT is not supported by this proxy", 1);
}
if (!(path = parse_url(purl, hostname, &portno, &proto))) {
error("Did not understand URL", 1);
}
if (proto != 80 && proto != 443) {
error("Unsupported protocol", 1);
}
if (upgrayedd && proto == 80) {
proto = 443;
if (portno == 80) portno = 443;
}
if (http09) {
/* convert into an HTTP/1.0 request, headers suppressed */
buffer = malloc(strlen(hostname) + strlen(path) + 256);
if (proto != portno) {
(void)sprintf(buffer,
"GET %s HTTP/1.0\r\n"
"Host: %s:%d\r\n"
"User-Agent: carl\r\n"
"Connection: close\r\n"
"\r\n",
(strlen(path) ? path : "/"), hostname, portno);
} else {
(void)sprintf(buffer,
"GET %s HTTP/1.0\r\n"
"Host: %s\r\n"
"User-Agent: carl\r\n"
"Connection: close\r\n"
"\r\n",
(strlen(path) ? path : "/"), hostname);
}
} else {
/* HTTP/1.0 or 1.1. read the rest of the headers */
char *has_host;
char hosthost[512], hostport[512];
int crlf = 0;
read_size = 0;
numcrs = 0;
with_headers = 1;
for(;;) {
if (!read(STDIN_FILENO, &c, 1))
return 1; /* underflow */
read_buffer[read_size++] = c;
if (read_size == sizeof(read_buffer)) return 1; /* overflow */
if (c == '\n') {
if (++numcrs == 2) break; else continue;
}
if (c == '\r') continue;
numcrs = 0;
}
numcrs = 0;
if (read_size < 4) return 1; /* unpossible */
if (read_buffer[(read_size-1)] == read_buffer[(read_size-2)]) {
/* ends in \n\n, hmm */
read_buffer[(read_size-1)] = '\0';
} else if (read_buffer[(read_size-4)] == '\r' &&
read_buffer[(read_size-1)] == read_buffer[(read_size-3)]) {
/* can only end in \r\n\r\n */
read_buffer[(read_size-2)] = '\0';
crlf = 1;
} else return 1; /* huh? */
/* compute host header. we need to either add it or check it.
some clients will append :80 (WebTV), so generate both. */
(void)sprintf(hostport, "Host: %s:%d%s",
hostname, portno, (crlf) ? "\r\n" : "\n");
(void)sprintf(hosthost, "Host: %s%s",
hostname, (crlf) ? "\r\n" : "\n");
if (has_host = strstr((char *)read_buffer, "Host: ")) {
/* to make this simpler, RFC 7230 gives us a way to cheat.
if there is a Host: header here, it must match the hostname
in the URL. if it doesn't, abort. */
/* multiple Host: headers? eat my shorts. */
if (strstr(++has_host, "Host: ")) return 1;
/* header is bogus? eat more of my shorts. */
if (proto != portno) { /* only allow host:port */
if (!strstr((char *)read_buffer, hostport)) return 1;
} else { /* allow either */
if (!strstr((char *)read_buffer, hosthost) &&
!strstr((char *)read_buffer, hostport)) return 1;
}
/* acceptable; use client header set */
buffer = malloc(strlen(method) + strlen(path) +
strlen((char *)read_buffer) + 256);
(void)sprintf(buffer, "%s %s %s%s",
method, (strlen(path) ? path : "/"),
read_buffer, (crlf) ? "\r\n" : "\n");
} else {
/* add Host: header */
buffer = malloc(strlen(method) + strlen(path) +
strlen((char *)read_buffer) +
strlen((portno != proto) ? hostport :
hosthost) + 256);
(void)sprintf(buffer, "%s %s %s%s%s",
method, (strlen(path) ? path : "/"),
read_buffer,
(portno != proto) ? hostport : hosthost,
(crlf) ? "\r\n" : "\n");
}
}
} else {
/* url provided on command line */
if (!(path = parse_url(url, hostname, &portno, &proto))) {
if (!quiet) fprintf(stderr, "%s: couldn't parse url\n", argv[0]);
return 1;
}
if (proto == 1080) {
if (!quiet) fprintf(stderr, "%s: socks only allowed for proxies\n",
argv[0]);
return 1;
}
if (proto != 80 && proto != 443) {
if (!quiet) fprintf(stderr, "%s: unsupported protocol\n", argv[0]);
return 1;
}
if (upgrayedd && proto == 80) {
proto = 443;
if (portno == 80) portno = 443;
}
buffer = malloc(strlen(hostname) + strlen(path) + 256);
if (proto != portno) {
(void)sprintf(buffer,
"%s %s HTTP/1.0\r\n"
"Host: %s:%d\r\n"
"User-Agent: carl\r\n"
"Connection: close\r\n"
"\r\n",
(head_only ? "HEAD" : "GET"), (strlen(path) ? path : "/"),
hostname, portno);
} else {
(void)sprintf(buffer,
"%s %s HTTP/1.0\r\n"
"Host: %s\r\n"
"User-Agent: carl\r\n"
"Connection: close\r\n"
"\r\n",
(head_only ? "HEAD" : "GET"), (strlen(path) ? path : "/"),
hostname);
}
}
signal(SIGPIPE, SIG_IGN);
signal(SIGALRM, timeout);
retrial: /* considered harmful */
if (!forever) (void)alarm(10);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("socket", 255);
/* nb: have to re-resolve during a fallback because we might have stale
data from other queries */
server = gethostbyname(hostname);
if (server == NULL) {
if (proxy) error("Host not found", 2);
if (!quiet) fprintf(stderr, "host not found: %s\n", hostname);
return 2;
}
memset((char *) &serv_addr, 0, sizeof(serv_addr)); /* blocking socket */
serv_addr.sin_family = AF_INET;
if (proxyurl) {
/* basic socks 4 client, no NO_PROXY support yet */
if (parse_url(proxyurl, sockshost, &socksport, &socksproto)) {
unsigned char spacket[9];
size_t sbytes = 0;
if (socksproto != 1080) {
if (!quiet) fprintf(stderr, "unsupported proxy protocol\n");
return 1;
}
if (server->h_length != 4) {
if (!quiet) fprintf(stderr, "IPv6 not supported for SOCKS4\n");
return 3;
}
spacket[0] = 0x04; /* socks v4 */
spacket[1] = 0x01; /* connect */
spacket[2] = portno >> 8;
spacket[3] = portno & 0xff;
spacket[4] = (unsigned char)server->h_addr[0];
spacket[5] = (unsigned char)server->h_addr[1];
spacket[6] = (unsigned char)server->h_addr[2];
spacket[7] = (unsigned char)server->h_addr[3];
spacket[8] = 0x00;
socksserver = gethostbyname(sockshost);
if (socksserver == NULL) {
if (!quiet) fprintf(stderr, "SOCKS proxy not found: %s\n",
sockshost);
return 2;
}
memcpy((char *)&serv_addr.sin_addr.s_addr,
(char *)socksserver->h_addr, socksserver->h_length);
serv_addr.sin_port = htons(socksport);
#if defined(macintosh)
mac_connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr),
"connect to SOCKS", 4);
#else
if (connect(sockfd,(struct sockaddr *)&serv_addr,
sizeof(serv_addr)) < 0)
error("connect to SOCKS", 4);
#endif
/* we should be able to send this much without blocking */
if (send(sockfd, spacket, 9, 0) != 9)
error("send to SOCKS", 4);
while ((read_size = recv(sockfd, (char *)&spacket[sbytes],
9-sbytes, 0)) > 0) {
sbytes += read_size;
if (sbytes == 8) break;
}
if (sbytes != 8 || spacket[0] != 0x00 ||
spacket[1] < 0x5a || spacket[1] > 0x5d) {
error("SOCKS connect failed", 5);
}
if (spacket[1] != 0x5a) {
if (proxy) error("SOCKS connect failed", 5);
if (!quiet) fprintf(stderr, "SOCKS connect: %i\n", spacket[1]);
return 5;
}
proxycon = 1;
} else {
error("illegal proxy URL", 1);
}
}
/* connect to host */
if (!proxycon) {
memcpy((char *)&serv_addr.sin_addr.s_addr, (char *)server->h_addr, server->h_length);
serv_addr.sin_port = htons(portno);
#if defined(macintosh)
mac_connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr),
"connect", 5);
#else
if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0)
error("connect", 5);
#endif
}
/* set up http or tls */
if (proto == 443) {
#if defined(__BEOS__)
#warning BeOS port currently limited to TLS 1.2
/* the stack overhead is apparently too much for it */
context = tls_create_context(0, TLS_V12);
#else
context = tls_create_context(0, (tls12) ? TLS_V12 : TLS_V13);
#endif
if (!tls_sni_set(context, hostname)) error("TLS context failure", 255);
tls_client_connect(context);
https_send_pending(sockfd, context);
} else {
/* on plain HTTP, try to send the initial request right now */
size_t buffer_index = 0;
size_t buffer_len = strlen(buffer);
while (buffer_len) {
int res = send(sockfd, (char *)&buffer[buffer_index],
buffer_len, 0);
if (res > 0) {
buffer_len -= res;
buffer_index += res;
}
}
}
/* read from socket and, if needed, stdin */
#if defined(__BEOS__)
(void)fcntl(fileno(stdin), F_SETFL, O_NONBLOCK);
#endif
if (proto == 80) {
for(;;) {
if (!forever) (void)alarm(10);
FD_ZERO(&fdset);
FD_SET(sockfd, &fdset);
#if !defined(__BEOS__)
FD_SET(STDIN_FILENO, &fdset);
(void)select(sockfd + 1, &fdset, NULL, NULL, NULL); /* wait */
#else
/* In BeOS and Win32 select() only works on sockets, not on
standard file handles, so we must ping-pong. */
tv.tv_sec = 0;
tv.tv_usec = TIMESLICE;
(void)select(sockfd + 1, &fdset, NULL, NULL, &tv); /* wait */
#endif
/* send any post-headers data, like POST forms, etc. */
if (stdin_pending()) {
size_t buffer_index = 0;
read_size = read(STDIN_FILENO, read_buffer, sizeof(read_buffer));
while (read_size) {
int res = send(sockfd, (char *)&read_buffer[buffer_index],
read_size, 0);
if (res > 0) {
read_size -= res;
buffer_index += res;
}
}
}
if (FD_ISSET(sockfd, &fdset)) {
if ((read_size = recv(sockfd, client_message, sizeof(client_message) , 0)) > 0) {
bytesread += read_size;
if (!with_headers) {
size_t i = 0;
for(i=0; i<read_size; i++) {
if (client_message[i] == '\r') continue;
if (client_message[i] == '\n') numcrs++;
else numcrs = 0;
if (numcrs == 2) { break; }
}
if (numcrs < 2) continue;
with_headers = 1; spoof10 = 0; /* paranoia */
for(i++; i<read_size; i++)
fwrite(&(client_message[i]), 1, 1, stdout);
} else {
if (spoof10) {
if (read_size > 7 &&
client_message[0] == 'H' &&
client_message[1] == 'T' &&
client_message[2] == 'T' &&
client_message[3] == 'P' &&
client_message[4] == '/' &&
client_message[5] == '1' &&
client_message[6] == '.' &&
client_message[7] == '1') {
client_message[7] = '0';
spoof10 = 0;
}
}
fwrite(client_message, read_size, 1, stdout);
}
} else break; /* ready socket, no bytes: connection closed */
}
/* some sort of signal, loop around */
}
} else if (proto == 443) {
for(;;) {
int i;
#if defined(__MACHTEN__)
/* it seems to get stuck here without this */
fprintf(stderr, "");
#endif
if (!forever) (void)alarm(10);
FD_ZERO(&fdset);
FD_SET(sockfd, &fdset);
#if !defined(__BEOS__)
FD_SET(STDIN_FILENO, &fdset);
(void)select(sockfd + 1, &fdset, NULL, NULL, NULL); /* wait */
#else
tv.tv_sec = 0;
tv.tv_usec = TIMESLICE;
(void)select(sockfd + 1, &fdset, NULL, NULL, &tv); /* wait */
#endif
/* service socket first, since we may still be setting up TLS */
if (FD_ISSET(sockfd, &fdset)) {
if ((read_size = recv(sockfd, client_message, sizeof(client_message) , 0)) > 0) {
int i = tls_consume_stream(context, client_message, read_size, validate_certificate);
if (i < 0) {
#if !defined(__BEOS__)
/* only fallback if allowed and if during hello
(elsewise it's an error) */
if (!tls12 && !tls13only && (tls_established(context) < 1)) {
#if DEBUG
fprintf(stderr, "warning: failed tls 1.3, error %d, falling back\n", i);
#endif
tls12 = 1;
close(sockfd);
tls_destroy_context(context);
goto retrial;
}
#endif
if (errno > 0) perror("tls_consume_stream");
if (!quiet) fprintf(stderr, "fatal TLS error: %d\n", i);
return 6;
}
https_send_pending(sockfd, context);
/* no point in anything further until TLS established */
if (!tls_established(context)) continue;
/* TLS up, try to send initial portion of request now */
if (!sent) {
tls_write(context, (unsigned char *)buffer, strlen(buffer));
https_send_pending(sockfd, context);
sent = 1;
}
/* prioritize POST data yet to be sent */
#if defined(__BEOS__)
if (stdindone) /* can't reliably detect stdin waiting */
#else
if (!stdin_pending() || stdindone)
#endif
/* drain everything waiting on the socket */
for(;;) {
/* drain TLS buffer first, in case we got it all */
while (read_size = tls_read(context, read_buffer, sizeof(read_buffer))) {
bytesread += read_size;
if (!with_headers) {
for(i=0; i<read_size; i++) {
if (read_buffer[i] == '\r') continue;
if (read_buffer[i] == '\n') numcrs++;
else numcrs = 0;
if (numcrs == 2) { break; }
}
if (numcrs < 2) continue;
with_headers = 1; spoof10 = 0; /* paranoia */
#if defined(__BEOS__)
/* whyyyyyy */
for(i++; i<read_size; i++)
write(STDOUT_FILENO, &(read_buffer[i]), 1);
#else
for(i++; i<read_size; i++)
fwrite(&(read_buffer[i]), 1, 1, stdout);
#endif
} else {
if (spoof10) {
if (read_size > 7 &&
read_buffer[0] == 'H' &&
read_buffer[1] == 'T' &&
read_buffer[2] == 'T' &&
read_buffer[3] == 'P' &&
read_buffer[4] == '/' &&
read_buffer[5] == '1' &&
read_buffer[6] == '.' &&
read_buffer[7] == '1') {
read_buffer[7] = '0';
spoof10 = 0;
}
}
#if defined(__BEOS__)
/* whyyyyyyy II: the wrath of wtf */
for(i=0; i<read_size; i++)
write(STDOUT_FILENO, &(read_buffer[i]), 1);
#else
fwrite(read_buffer, read_size, 1, stdout);
#endif
}
}
/* go back for more */
if ((read_size = recv(sockfd, client_message, sizeof(client_message) , 0)) <= 0) break;
i = tls_consume_stream(context, client_message, read_size, validate_certificate);
if (i < 0) {
if (errno > 0) perror("tls_consume_stream");
if (!quiet) fprintf(stderr, "fatal TLS error: %d\n", i);
return 6;
}
}
} else break; /* ready socket, no bytes: connection closed */
}
/* send any post-headers data, like POST forms, etc. */
if (sent) stdindone = 1; /* default done when request sent */
if (stdin_pending() && sent) {
/* no point until TLS is established */
if (!tls_established(context)) continue;
read_size = read(STDIN_FILENO, read_buffer, sizeof(read_buffer));
if (read_size > 0) {
tls_write(context, (unsigned char *)read_buffer, read_size);
https_send_pending(sockfd, context);
stdindone = 0; /* prioritize STDIN on future selects */
}
}
}
} else { /* profit! */ }
#if DEBUG
fprintf(stderr, "proper exit, bytes left=%d\n", context->application_buffer_len);
#endif
if (!bytesread) {
if (proto == 443 && context->error_code) {
(void)sprintf((char *)read_buffer,
"TLS alert received: %d\n", context->error_code);
error((char *)read_buffer, 6);
}
error("No data received", 253);
}
free(buffer);
return 0;
}
================================================
FILE: carl.md
================================================
# carl(1) - Crypto Ancienne Resource Loader
Crypto Ancienne
```
carl [options] url
```
<a name="description"></a>
# Description
**carl**
is both a demonstration application for the Crypto Ancienne TLS library and a utility reminiscent of the much more comprehensive
**curl**(1),
of which its name is a desperate pun. It may also be more suitable as a
**curl**(1)
substitute for the older systems that Crypto Ancienne caters to, since
it has no prerequisites other than a compatible C compiler.
Like its inspiration,
**carl**
fetches URLs, emitting them to standard output. However,
**carl**
only supports HTTP and HTTPS (and only HTTP/0.9, HTTP/1.0 and HTTP/1.1), although it will also parse SOCKS URLs and use them as proxies (see
**ENVIRONMENT**).
**carl**
can also accept complete
HTTP and HTTPS requests over standard input (see
**PROXY**
**MODE**).
If connected to
**inetd**(8)
or a similar utility, this can act as a complete proxy solution, including for some browsers which may not speak HTTPS or
current TLS versions themselves but can be trained or tricked to send requests for
**https://**
URLs to it.
<a name="options"></a>
# Options
In general, options do not match
**curl**(1)'s.
* **-q**
Quiet mode; no verbose errors are displayed (see
**EXIT**
**STATUS**).
* **-t**
Disable timeouts. Otherwise, transactions that take longer than 10 seconds are aborted. Necessary for slower systems that may not negotiate TLS quickly enough. Given that Crypto Ancienne specifically caters to such systems, this option may become the default in future versions.
* **-H**
Use
**HEAD**
as the request method instead of
**GET**.
In this mode, HTTP(S) headers are displayed automatically, along with any residual message body that may be transmitted by some servers. Other methods such as
**POST**
must be specified as proxy requests (i.e., sent over standard input when
**-p**
is specified).
* **-i**
Dump both headers and body, even if
**-H**
isn't specified. Irrelevant in proxy mode (when
**-p**
is specified).
* **-N**
Ignore the
**ALL_PROXY**
environment variable, if it exists (see
**ENVIRONMENT**).
* **-u**
Treat all HTTP URLs as HTTPS, even if they are specified as HTTP. This includes URLs received in proxy mode (when
**-p**
is specified).
* **-s**
Downgrade HTTP/1.1 replies to HTTP/1.0 for consumers or clients which are intolerant. Irrelevant if headers are not displayed (i.e., without
**-H**,
**-p**
or
**-i**).
* **-2**
Maximally negotiate TLS 1.2 instead of TLS 1.3. This is primarily for analysing handshake failures; under typical circumstances requiring this option to access a site should be considered a bug.
* **-3**
Conversely, do not allow fallbacks to a TLS 1.2 context if negotiating a TLS 1.3 context fails. By default
**carl**
will retry such connections to account for those hosts that genuinely support TLS 1.2 but not any of the ciphers that TLS 1.2 and TLS 1.3 would have in common. These sites are getting fewer and fewer, and thus this option may become the default in future versions.
* **-p**
Enables proxy mode (see
**PROXY**
**MODE**).
**-i**,
**-q**,
and
**-H**,
if they are specified, are ignored. If a URL is provided, it may only be a
**socks://**
or
**socks5://**
URL, which is used as a SOCKS proxy for
**carl**
to relay through (see the
**ALL_PROXY**
environment variable in
**ENVIRONMENT**).
* **-v**
Display version string (the same as the main library).
* **-h**
Display a synopsis of these options.
<a name="proxy-mode"></a>
# Proxy Mode
If the
**-p**
option is specified,
**carl**
will accept a full proxy client request for an
**http://**
or
**https://**
URL from standard input. It must be formatted as a standard HTTP proxy request with method
and fully-specified URL minimally compliant to RFC 7230, though
**carl**
is tolerant, and will quietly adjust client requests as needed or requested (see also the
**-u**
and
**-s**
options). A full HTTP reply with all remote headers will be sent in response.
The request must be delimited by the standard two-CRLF separator. If the method is intended to send data to the server, such as
**POST**,
the payload may trail the request headers after it.
**carl**
does no encoding of this data; your application must do that itself.
In proxy mode, the _url_ argument may only be used to specify a SOCKS proxy through which the request will be forwarded. If the
**ALL_PROXY**
environment variable exists, specifying a SOCKS URL on the command line will override it (or use
**-N**
to ignore it; see
**ENVIRONMENT**).
Otherwise,
**carl**
will connect directly.
The
**CONNECT**
method is intentionally not implemented.
**carl**
does not bind any server port itself. However, because this mode accepts data on standard input, any
**inetd**(8)
or
**inetd**(8)-like
superserver environment such as
**xinetd**(8)
or
**micro_inetd**(1)
can be used to make it accessible on the network. _Careful: if you bind an external interface, you've just made your computer into an open HTTP proxy!_
**carl**
implements no access controls or authentication, so check your superserver's documentation on how to only bind an internal interface or the loopback.
<a name="environment"></a>
# Environment
* **ALL_PROXY**
**carl**
has built-in SOCKSv4 client support. If a SOCKS URL (either
**socks://**
or
**socks5://**,
which is treated as a synonym) is specified in this environment variable, all requests will be forwarded through it.
If a port number is not specified in the URL, it is assumed to be 1080. Any provided path or arguments are ignored.
**carl**
does not support authentication or SOCKSv5 features, and requires your DNS be able to resolve hostnames.
* This variable is ignored if
**-N**
is specified on the command line, and it is overridden in proxy mode
(**-p**)
if a SOCKS URL is specified on the command line.
**NO_PROXY**
is not currently implemented.
<a name="exit-status"></a>
# Exit Status
A possibly helpful message may also appear unless it is suppressed by
**-q**.
These exit return codes may be expanded in future versions.
* **0**
No error.
* **1**
The request is pathological (nonsense, inappropriate or incomplete). This can also occur when a non-SOCKS proxy is provided
(**carl**
does not talk to other HTTP proxies; they are vapid and uninteresting at parties).
* **2**
The host or proxy host could not be resolved.
* **3**
The host resolved to an IPv6 address, but
**carl**
doesn't support those yet.
* **4**
The connection to the SOCKS proxy failed.
* **5**
The connection to the HTTP(S) server failed.
* **6**
The TLS response from the HTTPS server could not be processed.
* **253**
No data was received.
* **254**
Timeout. Consider using
**-t**
if the system is slower and the request should have worked.
* **255**
General failure.
<a name="notes"></a>
# Notes
**carl**
does not currently evaluate certificates for validity, so its encryption support is best considered opportunistic and it
should not be used for high-security environments.
<a name="see-also"></a>
# See Also
**curl**(1)
<a name="home-page"></a>
# Home Page
https://github.com/classilla/cryanc
<a name="author"></a>
# Author
(C)2020-3 Cameron Kaiser and Contributors. All rights reserved. Additional copyrights apply; see the home page for full credits. BSD license.
================================================
FILE: carl_mpw.sit.hqx
================================================
(This file must be converted with BinHex 4.0)
:"fe`GbjcDA3!8dP8090*9#%!N!3(2`#3"!GM8h4eCQC*G#!SBbNa16Nh,6)`-$)
J3@aKC'4TEL"6HA0dC@ec,#"*EQ-Z,#"SG(4`1Lm[Gj!$,Q&XB@4ND@jcHA-ZBfp
Y,e0dG@CQ5A3[$3SD!!83!!!(2`#3!h)!!3#3!h)5J`fPT9*PFf9bGQ9NTD8!TC!
%!3!!-`"!i%BaaZ"'EBi!N!d$)pi!N!2j!!!1lJ!!"RB!!Qe`G`!3BB`!N!J$i2q
3"!#3%U@3"!%!!$!!32rrRC!!rrqGN!!!!!3U!*!(FJ!!e4ArN!3!N!UPN!3"!!!
q!!$J4M)6i%Bb%`#3!h)!!!3U!*!$FJ!1l2%!!!DS!!!#BJ#3"!m!3h*j3@jM4e9
655jMF(!!!@U[9%9B9&)UBfJ"!*!C!Ai!N!0I!*!%$`"#`G8(%mPY1BkXpfff4h,
hP&`fPHPdiY`@#kYN4LJr,DBE$%r#52FFKGQlRd5$CKdGjHH`bXG902a2&rFQRke
%K)I4#ZjA`aK-&[9JBb*CPYpD*Da-E!#'EZ#,ipm[!%,"e)jH8QEYYM+ZZp(Rb%F
MZqNI9E@TDImM6F0fbJdlDm#Sm+B9@m&[L)d[V()cM1iL[B!-43B-pZD&MPRkb@)
M21LXMIlZd3"!#mP-0T0qe@Z"L"eQ%$`LN[IiYl&&HQC1-9BfQTeY(p5KpD6DED`
,GV[1$LSR&ip#"11+R9k&*dRf365C*$CGA#L4qe'M3ieE88r@iLA)'XecYR!&-B8
`XIYcGUaNL6k%@4VpSP[R&Qj5b1ZMR"@+CPjYYENSL`NapAT'rK3C9BS3U#181FK
'SpR))UNRj'A'#fV)+02YY09#f454rYhFMlr8k,q(-Yl1i)cLe'IJfm8-AUB-dVF
J,)iVf5,*H5k(B5Z$ZF4$lkp%ld1Z$lSj$92cX-qr,ET4kNJ+r1&jC-eP'8`llqr
FIb&-8X2Ra5pKUZET+S4q$"d9'DT*I'H'R,Md5H2%Y+X2Hd+L4Kj%U8#1J'L4B99
C!K-mb%J$l1l)1Ae%eVce4G%UHclkTl-SX)eC+15b5TT8,AZY+YLpCDQ$TJY*jp`
[*r@E")YK&3B0AIXP*FqA`V*69BTmLUJql`F`0,%@Kl$'b,RNl249N!$G6E@Jd6*
Zm`IU-INDU6[C4'e-SAd5KC`4"(-L'ZbGll6aDLRee`d$9Fh1kQ6E$1e6`lIFZak
hjkJ31eS%M,q2,QA2*4q[GQ1bkReK#%VGAa"Le8ZkcMR$fXPlaiUSh[1B2#MTKr+
$CeEa,"(4Q-m'r'[Ml`mUaJ)`KP@fhA#bDEIT+-YfAdHTlS,&Y8SIN35#X8,p)2E
j9RlS&p+02Li'qV$&mN`KUSaiTC!%!3!!1!!!i%BafH"'DKB!N!2j!*!$b3#3!h)
!#2R(!!!&'J!!!Lm!N!32!%eKDf9QD@aP!!&KQe4&@&408&-J!3#3'3'Z!*!$I!#
3"!m!3X(8kN$5bh)@kD[*Y#X@09"p404TA$#a3BG)#SCfQMF"2bZ4`'I1JL-YjC!
!A1[pP"rK&5!&*QH@H)m-e$44%rkIr*!!c@NpV-hB8"YkM9YV$a9epd$@Xi*&Xq2
JXcH'GF*aH49B#pBBG9r@ca%620rAhI8piqHjj[UjJUX`3X(8Z"G9kEqH2AhN!FX
D)D#fk$%K$3AImmB)Iae[bjrJl$kLUe&`%d(CH#4GKqF4jfZb(dX&c5R2mUk1)cj
-["+Y5`(0EedbmY0JTKZ@`Vdm3`FTRQ4*XVmTTJ@KRarG1-2D"&[QE%Sj2BG[ZlI
FeZhXi09&C!3D4$iFQ+VrQEp,hTZ5bqH(54`(*f4SP06%*@*+0dii8'bG0XPReIa
@aiQrG1P%AaPIN!"ADp%U'&MASY$U(MRIbTSH2Q"[k%DIASBMp3qGqX-RDHhKjIh
F#cmFX89TeBfENmSSkqP0d%l"d#1TLVj![0XEc4EK$lLmPK'Zhr-3%B4ijl'`+'e
8UNI[*04C-BQFrp%d!#PiRqCS1`B3!GY'cDJe29i&*jTf,KIIBZhj8&K$c2kPJGL
kL!feQHh[kr-NB3-'MP$2Bp13!"F+lQ'%G$EQh%hM&LVU*2RleUSPJLh4E%EdLVK
`0Ll&d4YDPfY#S1NcSjPY)IDIJ[3P*QAk6%V'&Y9r([[bmRbcT80IqPB5[YT&p*U
Y(j!!k,qri86&qI1$Rb'Cl13'J%XCV,fFZ%qICM(R*p&kh9d#%KJe2'dU0Tc)kaP
SiS8AUp9T+km+Ce*Ni0XD8D1'ZBND(Zj3DFjXH$N9Bj5#dN"'D#NHLBckq)b'r1L
1!mPCf14Fl1"`q'$hYl&15h)$ZE-&KXZ9Nje4NV%rH,VCm!D9hYRHqTk+YUS1NX-
L,SfVcGcj`Jk)k#+e-FeLHr18q,fZ!!!!:
================================================
FILE: cryanc.c
================================================
/* Crypto Ancienne v2.0
A pre-C99 cryptography library for the Internet of Old Things
DISCLAIMER:
The use of this library does not make your application cryptographically
secure, and certain systems may entirely lack any technological means to
make that possible. Its functionality and security should be regarded as,
at best, "good enough to shoot yourself in the foot with."
Copyright (c) 2020-3 Cameron Kaiser and contributors. All rights reserved.
Based on TLSe. Copyright (c) 2016-2021, Eduard Suica.
Based on libtomcrypt. By Tom St Denis and contributors. Unlicense.
Based on public domain works by D. J. Bernstein.
Allegedly includes an alleged ARC4 random routine from OpenBSD (allegedly).
Copyright (c) 1996 David Mazieres.
All rights reserved.
BSD license.
*/
/********************************************************************************
Copyright (c) 2016-2023, Eduard Suica
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.
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.
********************************************************************************/
#ifndef TLSE_C
#define TLSE_C
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#ifdef _WIN32
#ifdef SSL_COMPATIBLE_INTERFACE
#include <winsock2.h>
#endif
#include <windows.h>
#include <wincrypt.h>
#ifndef strcasecmp
#define strcasecmp stricmp
#endif
#else
/* hton* and ntoh* functions */
#if defined(__BEOS__)
/* weird */
#include <netdb.h>
#else
#include <arpa/inet.h>
#endif
#include <unistd.h>
#include <errno.h>
#endif
#include <limits.h>
#include <sys/time.h>
/*****************************************************************************
Start of architecture-dependent recipes
****************************************************************************/
/* AIX: not compliant with SUS until 5L */
#if defined(_AIX)
#if defined(_AIX51)
/* AIX 5L and up */
#warning compiling for current AIX
#else
/* AIX 4 and under */
#warning compiling for AIX before 5L
#include <stdarg.h>
#define NOT_POSIX 1
#endif
#if defined(__ibmxl__)
#warning not tested with xlc
#endif
#endif
/* IRIX on MIPS (MIPSPro preferred, probably works with Nekoware gcc) */
#if defined(sgi) || defined(__sgi)
#warning compiling for IRIX on MIPS
#ifdef __GNUC__
#warning not tested on gcc
#else
#ifdef _SGI_COMPILER_VERSION
#if (_SGI_COMPILER_VERSION < 744)
#warning not tested on this version of MIPSPro, consider c99
#endif
#else
#ifdef _COMPILER_VERSION
#warning not tested on this version of MIPSPro, consider c99
#endif
#endif
#endif
#define NO_FUNNY_ALIGNMENT 1 /* reacts badly to unaligned pointer access */
#endif
/* BeOS R5 (BeBox or GTFO) */
#if defined(__BEOS__)
#warning compiling for BeOS R5 - PARTIALLY WORKING, see notes
/* mostly POSIX but not SUS */
#define NOT_POSIX 1
#include <stdarg.h>
#include <inttypes.h>
#include <endian.h>
#if __POWERPC__
#ifndef __BIG_ENDIAN__
#define __BIG_ENDIAN__ 1
#endif
#endif
/* pad libc */
#define usleep(x) snooze(x)
#if defined(__MWERKS__)
#warning Metrowerks compiler detected - DISABLE OPTIMIZATION
/* Mwerks enforces a 32K function-local data limit which some functions hit,
which is made worse by BeOS's pathetic 256K stack limit per thread. */
#define BIG_STRING_SIZE 0x0800
#else
#ifdef __GNUC__
#if __POWERPC__
#warning Fred Fish egcs detected - check your include paths are correct
#else
#warning Intel gcc - not supported
#endif
#else
/* huh? */
#warning this compiler is not supported
#endif
#endif
#endif
/* SunOS 4 and Solaris 2+ */
#if defined(sun) || defined(__sun)
#if defined(__SVR4) || defined(__svr4__)
/* Solaris is not officially supported yet */
#warning compiling for Solaris
#define NOT_POSIX 1
#include <stdarg.h>
#include <inttypes.h>
#if (defined(__sparc) || defined(__sparc__))
#define NO_FUNNY_ALIGNMENT 1
#define __BIG_ENDIAN__ 1
#endif
#else
/* SunOS 4 or OS/MP ... needs a LOT of help! */
#warning compiling for SunOS 4 and OS/MP
#include <stdarg.h>
/* Seems to lack the usual macros for endianness. */
#ifndef __BIG_ENDIAN__
#define __BIG_ENDIAN__ 1
#endif
#define NOT_POSIX 1
#define LTC_NO_PROTOTYPES 1 /* clashes with qsort() */
#define NO_FUNNY_ALIGNMENT 1 /* reacts badly to unaligned pointer access */
/* SunOS 4 realloc() doesn't work like other implementations */
char *_crealloc(void *p, unsigned s) { return (p) ? realloc(p,s) : malloc(s); }
#define TLS_REALLOC(p,s) _crealloc(p,s)
#define XREALLOC _crealloc
/* pad libc a bit */
#define memmove(d,s,l) (bcopy((char *)(s),(char *)(d),(l)))
#define raise(s) (kill(getpid(),s))
#endif
#endif
/* MachTen and Power MachTen */
#if defined(__MACHTEN__)
#warning compiling for MachTen
#define NOT_POSIX 1
#include <stdarg.h>
/* /usr/macppc/include/machine/types.h is incomplete */
typedef long long int64_t;
typedef unsigned long long u_int64_t;
#endif
/* Tru64 on Alpha, may also work for old-sk00l Digital UNIX or OSF/1 */
#if defined (__digital__) && defined (__unix__)
#warning compiling for Tru64
#if defined (__alpha) && defined (__DECC)
#warning DEC/Compaq C compiler on Alpha - must compile with -misalign
/* mostly POSIX but not SUS */
#define NOT_POSIX 1
#define __WCHAR_TYPE__ 1 /* seems to already have it */
/* big surprise, Alpha hates unaligned pointers. yeah, you were shocked.
however, NO_FUNNY_ALIGNMENT is still not enough for it, so no point
in using it yet! */
/* #define NO_FUNNY_ALIGNMENT 1 */
#include <stdarg.h>
#include <inttypes.h>
#else
#warning unsupported configuration
#endif
#endif
/* SCO Xenix and Unix 4.2 (pre-OpenServer)*/
#if defined (M_XENIX) && !defined(_SCO_DS)
#if !defined(M_UNIX) /* Xenix 2.3.4 */
#warning compiling for SCO Xenix
#include <stddef.h>
/* Xenix's realloc is also weird */
char *_crealloc(void *p, unsigned s) { return (p) ? realloc(p,s) : malloc(s); }
#define TLS_REALLOC(p,s) _crealloc(p,s)
#define XREALLOC _crealloc
/*from https://www.samba.org/WinFS_report/winfs_dev/sun/solaris/source/2.50a/replace.c */
char *strstr(char *s, char *p)
{
int len = strlen(p);
while ( *s != '\0' ) {
if ( strncmp(s, p, len) == 0 )
return s;
s++;
}
return NULL;
}
#define memmove(d,s,l) (bcopy((char *)(s),(char *)(d),(l)))
#else
#warning compiling for SCO Unix
#endif /* Xenix 2.3.4 */
#define LTC_NO_PROTOTYPES
#define NOT_POSIX 1
#include <sys/types.h>
#include <stdarg.h>
int usleep(unsigned int useconds)
{
struct timeval temptval;
if (useconds <= 0) return;
temptval.tv_sec = useconds / 1000000;
temptval.tv_usec = useconds % 1000000;
if (select(0,NULL,NULL,NULL,&temptval) == -1 && errno != 4)
{
perror("sleep with select");
exit(1);
}
}
#endif /* SCO Xenix, Unix, ODT */
/* Distinguish NeXTSTEP/OpenSTEP from Rhapsody and from Mac OS X */
#if defined(__MACH__)
#if !defined(__APPLE__)
/* NeXTSTEP (at least 3.3)/OpenSTEP 4+ */
#warning compiling for NeXTSTEP-OpenSTEP
#define NOT_POSIX 1
#define LTC_NO_PROTOTYPES 1 /* conflicts with built-in defs */
#include <stdarg.h>
#include <sys/signal.h>
#else
#if !defined(__APPLE_CC__)
#error unsupported compiler on Darwin-like platform
#error send your patch to fix this - you can help
#else
#if (__APPLE_CC__ == 1)
/* MacPorts compiler, assume this is SUS */
#warning compiling for MacPorts toolchain
#else
#if (__APPLE_CC__ < 913)
/* Rhapsody to early OS X class compiler, including Mac OS X Server v1.x */
#warning compiling for Rhapsody-Mac OS X Server-Public Beta
#include <stdarg.h>
#define NOT_POSIX 1
#else
/* Mac OS X with Xcode-provided gcc or clang */
#warning compiling for Mac OS X with Xcode
#endif
#endif
#endif
#endif
#endif
/* A/UX (might work with 2, tested on 3.1) */
#if defined(__AUX__)
/* Needs BSD compat library for usleep. */
#warning compiling for A/UX - remember to include -lbsd or /lib/libbsd.a
#include <stdarg.h>
/* Seems to lack the usual macros for endianness. */
#ifndef __BIG_ENDIAN__
#define __BIG_ENDIAN__ 1
#endif
#define NOT_POSIX 1
#endif
/* HP-UX (tested on 11.31 IA-64 and 10.20/11.11/11.23 PA-RISC) */
#if defined(__hpux)
#if !defined(__ia64) && !defined(__hppa)
#error HP-UX support not tested on other architectures besides ia64 and hppa
#error send your patch to fix this - you can help
#endif
#define __BIG_ENDIAN__ 1
#define NO_FUNNY_ALIGNMENT 1
/* HP-UX 10.x and under */
#if defined(oldhpux)
#warning compiling for HP-UX before 11
#define NOT_POSIX 1
#include <stdarg.h>
#include <sys/_inttypes.h>
#include <unistd.h>
#else
/* HP-UX 11 and up */
#warning compiling for current HP-UX
#endif
#endif
/* AmigaOS with ADE gcc 2.95.3 and ixemul */
#if defined(__amiga__) || defined(__AMIGA__)
#warning compiling for AmigaOS
#if !defined(__ixemul)
#error currently requires ixemul for proper POSIX semantics
#error send your patch to fix this - you can help
#endif
#if !defined(__mc68000__) && !defined(__mc68000) && !defined(mc68000)
#warning not a 68K target, assuming native PowerPC, unsupported
#endif
#if !defined(__GNUC__)
#warning non-gcc compiler detected, unsupported
#else
#warning remember to use -mstackextend
#endif
#define NOT_POSIX 1
#include <stdarg.h>
#include <unistd.h>
#ifndef __BIG_ENDIAN__
#define __BIG_ENDIAN__ 1
#endif
/* Don't let the stack bloat */
#define BIG_STRING_SIZE 0x1000
#endif
/* Mac OS with MrC (possibly also SC). This is REALLY BUGGY. */
/* MrC doesn't understand #warning, so we turn off our helpful diagnostics. */
#ifdef MPW_C
#include <stdarg.h>
#define NOT_POSIX 1
#define __BIG_ENDIAN__ 1
/* This works around issues with the compiler (PowerPC handles misaligned
accesses just fine). */
#define NO_FUNNY_ALIGNMENT 1
/* This makes it a bit more stable. Not sure what the optimum value is. */
#define BIG_STRING_SIZE 0x0800
#define inline
/* ^ ... to nothing. These compilers don't understand this keyword, but they
automatically inline short functions. */
#endif
/* Architectures we will always break up aligned accesses on */
#ifndef FUNNY_ALIGNMENT_OK
#ifndef NO_FUNNY_ALIGNMENT
#if (defined(mips) || defined(_mips) || defined(__mips) || defined(__mips__) || defined(_MIPS_) || defined(__MIPS__) || defined(__MIPSEL__) || defined(__MIPSEB__))
#warning detected MIPS architecture, forcing aligned memory access
#define NO_FUNNY_ALIGNMENT 1
#endif
#if (defined(__sparc) || defined(__sparc__))
#warning detected SPARC architecture, forcing aligned memory access
#define NO_FUNNY_ALIGNMENT 1
#endif
#if (defined(__hppa) || defined(__hppa__))
#warning detected PA-RISC architecture, forcing aligned memory access
#define NO_FUNNY_ALIGNMENT 1
#endif
#if (defined(__sh__))
#warning detected SuperH architecture, forcing aligned memory access
#define NO_FUNNY_ALIGNMENT 1
#endif
#endif
#endif
/*****************************************************************************
End of architecture-dependent recipes (mostly)
****************************************************************************/
#ifndef BIG_STRING_SIZE
#define BIG_STRING_SIZE 0xFFFF
#endif
/* We use __BIG_ENDIAN__ as a canonical macro, so flatten any variant defs. */
#ifndef __BIG_ENDIAN__
#if defined(__BYTE_ORDER) && defined(__BIG_ENDIAN)
#if (__BYTE_ORDER == __BIG_ENDIAN)
#define __BIG_ENDIAN__ 1
#endif
#endif
#endif
#ifndef __BIG_ENDIAN__
#if defined(BYTE_ORDER) && defined(BIG_ENDIAN)
#if (BYTE_ORDER == BIG_ENDIAN)
#define __BIG_ENDIAN__ 1
#endif
#endif
#endif
#if __BIG_ENDIAN__
#ifndef MPW_C
#warning big endian platform
#endif
#else
#warning little or middle endian platform
#endif
#ifdef NO_FUNNY_ALIGNMENT
/* These are inherently big endian, since they replace htons()/ntohs(). */
#define __toshort(w,x) ((w[(x)] << 8) + (w[(x)+1]))
void __short(void *where, unsigned int index, unsigned short value) {
char *p = (char *)where;
p[index] = value >> 8;
p[index+1] = (value & 0xff);
}
#if __BIG_ENDIAN__
/* Just memcpy() the long long dudes */
#else
/* Convert native long long to big endian. */
void __llong(void *where, uint64_t value) {
char *p = (char *)where;
p[7] = value & 0xff;
p[6] = value >> 8;
p[5] = value >> 16;
p[4] = value >> 24;
p[3] = value >> 32;
p[2] = value >> 40;
p[1] = value >> 48;
p[0] = value >> 56;
}
#endif
#endif
/* Default: assume POSIX-SUS (current Linux and BSDs, etc.) */
#if !defined(NOT_POSIX)
#warning compiling for POSIX-SUS
#include <stdint.h>
#include <unistd.h>
#include <stdarg.h>
#else
#ifndef MPW_C
#warning compiling with compatibility stubs
#endif
/* Sys-dep work arounds for old headers */
/* provide definitions if we don't have stdint.h. */
/* Mach and inttypes.h define these elsewhere. */
#if !defined(_INTTYPES_H_) && !defined(_INTTYPES_H) && !defined(__INTTYPES_INCLUDED)
#if !defined(_MACHTYPES_H_)
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;
#ifdef __64BIT__
typedef signed long int64_t;
typedef int64_t intptr_t;
#else
/* ILP32 */
typedef signed long long int64_t;
typedef int32_t intptr_t;
#endif
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
#ifdef __64BIT__
typedef unsigned long uint64_t;
typedef uint64_t uintptr_t;
#else
/* ILP32 */
typedef unsigned long long uint64_t;
typedef uint32_t uintptr_t;
#endif
#else
/* Rhapsody and other Mach derivatives need these but not the above */
typedef u_int8_t uint8_t;
typedef u_int16_t uint16_t;
typedef u_int32_t uint32_t;
typedef u_int64_t uint64_t;
#ifdef __64BIT__
typedef int64_t intptr_t;
typedef uint64_t uintptr_t;
/* We can't typedef these on OS X Public Beta or the build will fail */
#else
#if !defined(__APPLE_CC__) || (__APPLE_CC__ < 784)
typedef int32_t intptr_t;
typedef uint32_t uintptr_t;
#endif
#endif
#endif
#endif
#endif
#define CRYPT 0x0117
#define LTC_NO_ROLC
/* LibTomMath, multiple-precision integer library -- Tom St Denis
* This has been modified to be dependent on the core Crypto Ancienne
* library by Cameron Kaiser and implement arc4random with extensions.
*
* LibTomMath is a library that provides multiple-precision
* integer arithmetic as well as number theoretic functionality.
*
* The library was designed directly after the MPI library by
* Michael Fromberger but has been written from scratch with
* additional optimizations in place.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tstdenis82@gmail.com, http://math.libtomcrypt.com
* Modified for Crypto Ancienne by Cameron Kaiser
*/
#ifndef BN_H_
#define BN_H_
#if !(defined(LTM1) && defined(LTM2) && defined(LTM3))
#if defined(LTM2)
#define LTM3
#endif
#if defined(LTM1)
#define LTM2
#endif
#define LTM1
#if defined(LTM_ALL)
#define BN_ERROR_C
#define BN_FAST_MP_INVMOD_C
#define BN_FAST_MP_MONTGOMERY_REDUCE_C
#define BN_FAST_S_MP_MUL_DIGS_C
#define BN_FAST_S_MP_MUL_HIGH_DIGS_C
#define BN_FAST_S_MP_SQR_C
#define BN_MP_2EXPT_C
#define BN_MP_ABS_C
#define BN_MP_ADD_C
#define BN_MP_ADD_D_C
#define BN_MP_ADDMOD_C
#define BN_MP_AND_C
#define BN_MP_CLAMP_C
#define BN_MP_CLEAR_C
#define BN_MP_CLEAR_MULTI_C
#define BN_MP_CMP_C
#define BN_MP_CMP_D_C
#define BN_MP_CMP_MAG_C
#define BN_MP_CNT_LSB_C
#define BN_MP_COPY_C
#define BN_MP_COUNT_BITS_C
#define BN_MP_DIV_C
#define BN_MP_DIV_2_C
#define BN_MP_DIV_2D_C
#define BN_MP_DIV_3_C
#define BN_MP_DIV_D_C
#define BN_MP_DR_IS_MODULUS_C
#define BN_MP_DR_REDUCE_C
#define BN_MP_DR_SETUP_C
#define BN_MP_EXCH_C
#define BN_MP_EXPORT_C
#define BN_MP_EXPT_D_C
#define BN_MP_EXPT_D_EX_C
#define BN_MP_EXPTMOD_C
#define BN_MP_EXPTMOD_FAST_C
#define BN_MP_EXTEUCLID_C
#define BN_MP_FREAD_C
#define BN_MP_FWRITE_C
#define BN_MP_GCD_C
#define BN_MP_GET_INT_C
#define BN_MP_GET_LONG_C
#define BN_MP_GET_LONG_LONG_C
#define BN_MP_GROW_C
#define BN_MP_IMPORT_C
#define BN_MP_INIT_C
#define BN_MP_INIT_COPY_C
#define BN_MP_INIT_MULTI_C
#define BN_MP_INIT_SET_C
#define BN_MP_INIT_SET_INT_C
#define BN_MP_INIT_SIZE_C
#define BN_MP_INVMOD_C
#define BN_MP_INVMOD_SLOW_C
#define BN_MP_IS_SQUARE_C
#define BN_MP_JACOBI_C
#define BN_MP_KARATSUBA_MUL_C
#define BN_MP_KARATSUBA_SQR_C
#define BN_MP_LCM_C
#define BN_MP_LSHD_C
#define BN_MP_MOD_C
#define BN_MP_MOD_2D_C
#define BN_MP_MOD_D_C
#define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
#define BN_MP_MONTGOMERY_REDUCE_C
#define BN_MP_MONTGOMERY_SETUP_C
#define BN_MP_MUL_C
#define BN_MP_MUL_2_C
#define BN_MP_MUL_2D_C
#define BN_MP_MUL_D_C
#define BN_MP_MULMOD_C
#define BN_MP_N_ROOT_C
#define BN_MP_N_ROOT_EX_C
#define BN_MP_NEG_C
#define BN_MP_OR_C
#define BN_MP_PRIME_FERMAT_C
#define BN_MP_PRIME_IS_DIVISIBLE_C
#define BN_MP_PRIME_IS_PRIME_C
#define BN_MP_PRIME_MILLER_RABIN_C
#define BN_MP_PRIME_NEXT_PRIME_C
#define BN_MP_PRIME_RABIN_MILLER_TRIALS_C
#define BN_MP_PRIME_RANDOM_EX_C
#define BN_MP_RADIX_SIZE_C
#define BN_MP_RADIX_SMAP_C
#define BN_MP_RAND_C
#define BN_MP_READ_RADIX_C
#define BN_MP_READ_SIGNED_BIN_C
#define BN_MP_READ_UNSIGNED_BIN_C
#define BN_MP_REDUCE_C
#define BN_MP_REDUCE_2K_C
#define BN_MP_REDUCE_2K_L_C
#define BN_MP_REDUCE_2K_SETUP_C
#define BN_MP_REDUCE_2K_SETUP_L_C
#define BN_MP_REDUCE_IS_2K_C
#define BN_MP_REDUCE_IS_2K_L_C
#define BN_MP_REDUCE_SETUP_C
#define BN_MP_RSHD_C
#define BN_MP_SET_C
#define BN_MP_SET_INT_C
#define BN_MP_SET_LONG_C
#define BN_MP_SET_LONG_LONG_C
#define BN_MP_SHRINK_C
#define BN_MP_SIGNED_BIN_SIZE_C
#define BN_MP_SQR_C
#define BN_MP_SQRMOD_C
#define BN_MP_SQRT_C
#define BN_MP_SQRTMOD_PRIME_C
#define BN_MP_SUB_C
#define BN_MP_SUB_D_C
#define BN_MP_SUBMOD_C
#define BN_MP_TO_SIGNED_BIN_C
#define BN_MP_TO_SIGNED_BIN_N_C
#define BN_MP_TO_UNSIGNED_BIN_C
#define BN_MP_TO_UNSIGNED_BIN_N_C
#define BN_MP_TOOM_MUL_C
#define BN_MP_TOOM_SQR_C
#define BN_MP_TORADIX_C
#define BN_MP_TORADIX_N_C
#define BN_MP_UNSIGNED_BIN_SIZE_C
#define BN_MP_XOR_C
#define BN_MP_ZERO_C
#define BN_PRIME_TAB_C
#define BN_REVERSE_C
#define BN_S_MP_ADD_C
#define BN_S_MP_EXPTMOD_C
#define BN_S_MP_MUL_DIGS_C
#define BN_S_MP_MUL_HIGH_DIGS_C
#define BN_S_MP_SQR_C
#define BN_S_MP_SUB_C
#define BNCORE_C
#endif
#if defined(BN_ERROR_C)
#define BN_MP_ERROR_TO_STRING_C
#endif
#if defined(BN_FAST_MP_INVMOD_C)
#define BN_MP_ISEVEN_C
#define BN_MP_INIT_MULTI_C
#define BN_MP_COPY_C
#define BN_MP_MOD_C
#define BN_MP_SET_C
#define BN_MP_DIV_2_C
#define BN_MP_ISODD_C
#define BN_MP_SUB_C
#define BN_MP_CMP_C
#define BN_MP_ISZERO_C
#define BN_MP_CMP_D_C
#define BN_MP_ADD_C
#define BN_MP_EXCH_C
#define BN_MP_CLEAR_MULTI_C
#endif
#if defined(BN_FAST_MP_MONTGOMERY_REDUCE_C)
#define BN_MP_GROW_C
#define BN_MP_RSHD_C
#define BN_MP_CLAMP_C
#define BN_MP_CMP_MAG_C
#define BN_S_MP_SUB_C
#endif
#if defined(BN_FAST_S_MP_MUL_DIGS_C)
#define BN_MP_GROW_C
#define BN_MP_CLAMP_C
#endif
#if defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C)
#define BN_MP_GROW_C
#define BN_MP_CLAMP_C
#endif
#if defined(BN_FAST_S_MP_SQR_C)
#define BN_MP_GROW_C
#define BN_MP_CLAMP_C
#endif
#if defined(BN_MP_2EXPT_C)
#define BN_MP_ZERO_C
#define BN_MP_GROW_C
#endif
#if defined(BN_MP_ABS_C)
#define BN_MP_COPY_C
#endif
#if defined(BN_MP_ADD_C)
#define BN_S_MP_ADD_C
#define BN_MP_CMP_MAG_C
#define BN_S_MP_SUB_C
#endif
#if defined(BN_MP_ADD_D_C)
#define BN_MP_GROW_C
#define BN_MP_SUB_D_C
#define BN_MP_CLAMP_C
#endif
#if defined(BN_MP_ADDMOD_C)
#define BN_MP_INIT_C
#define BN_MP_ADD_C
#define BN_MP_CLEAR_C
#define BN_MP_MOD_C
#endif
#if defined(BN_MP_AND_C)
#define BN_MP_INIT_COPY_C
#define BN_MP_CLAMP_C
#define BN_MP_EXCH_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_CLAMP_C)
#endif
#if defined(BN_MP_CLEAR_C)
#endif
#if defined(BN_MP_CLEAR_MULTI_C)
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_CMP_C)
#define BN_MP_CMP_MAG_C
#endif
#if defined(BN_MP_CMP_D_C)
#endif
#if defined(BN_MP_CMP_MAG_C)
#endif
#if defined(BN_MP_CNT_LSB_C)
#define BN_MP_ISZERO_C
#endif
#if defined(BN_MP_COPY_C)
#define BN_MP_GROW_C
#endif
#if defined(BN_MP_COUNT_BITS_C)
#endif
#if defined(BN_MP_DIV_C)
#define BN_MP_ISZERO_C
#define BN_MP_CMP_MAG_C
#define BN_MP_COPY_C
#define BN_MP_ZERO_C
#define BN_MP_INIT_MULTI_C
#define BN_MP_SET_C
#define BN_MP_COUNT_BITS_C
#define BN_MP_ABS_C
#define BN_MP_MUL_2D_C
#define BN_MP_CMP_C
#define BN_MP_SUB_C
#define BN_MP_ADD_C
#define BN_MP_DIV_2D_C
#define BN_MP_EXCH_C
#define BN_MP_CLEAR_MULTI_C
#define BN_MP_INIT_SIZE_C
#define BN_MP_INIT_C
#define BN_MP_INIT_COPY_C
#define BN_MP_LSHD_C
#define BN_MP_RSHD_C
#define BN_MP_MUL_D_C
#define BN_MP_CLAMP_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_DIV_2_C)
#define BN_MP_GROW_C
#define BN_MP_CLAMP_C
#endif
#if defined(BN_MP_DIV_2D_C)
#define BN_MP_COPY_C
#define BN_MP_ZERO_C
#define BN_MP_INIT_C
#define BN_MP_MOD_2D_C
#define BN_MP_CLEAR_C
#define BN_MP_RSHD_C
#define BN_MP_CLAMP_C
#define BN_MP_EXCH_C
#endif
#if defined(BN_MP_DIV_3_C)
#define BN_MP_INIT_SIZE_C
#define BN_MP_CLAMP_C
#define BN_MP_EXCH_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_DIV_D_C)
#define BN_MP_ISZERO_C
#define BN_MP_COPY_C
#define BN_MP_DIV_2D_C
#define BN_MP_DIV_3_C
#define BN_MP_INIT_SIZE_C
#define BN_MP_CLAMP_C
#define BN_MP_EXCH_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_DR_IS_MODULUS_C)
#endif
#if defined(BN_MP_DR_REDUCE_C)
#define BN_MP_GROW_C
#define BN_MP_CLAMP_C
#define BN_MP_CMP_MAG_C
#define BN_S_MP_SUB_C
#endif
#if defined(BN_MP_DR_SETUP_C)
#endif
#if defined(BN_MP_EXCH_C)
#endif
#if defined(BN_MP_EXPORT_C)
#define BN_MP_INIT_COPY_C
#define BN_MP_COUNT_BITS_C
#define BN_MP_DIV_2D_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_EXPT_D_C)
#define BN_MP_EXPT_D_EX_C
#endif
#if defined(BN_MP_EXPT_D_EX_C)
#define BN_MP_INIT_COPY_C
#define BN_MP_SET_C
#define BN_MP_MUL_C
#define BN_MP_CLEAR_C
#define BN_MP_SQR_C
#endif
#if defined(BN_MP_EXPTMOD_C)
#define BN_MP_INIT_C
#define BN_MP_INVMOD_C
#define BN_MP_CLEAR_C
#define BN_MP_ABS_C
#define BN_MP_CLEAR_MULTI_C
#define BN_MP_REDUCE_IS_2K_L_C
#define BN_S_MP_EXPTMOD_C
#define BN_MP_DR_IS_MODULUS_C
#define BN_MP_REDUCE_IS_2K_C
#define BN_MP_ISODD_C
#define BN_MP_EXPTMOD_FAST_C
#endif
#if defined(BN_MP_EXPTMOD_FAST_C)
#define BN_MP_COUNT_BITS_C
#define BN_MP_INIT_C
#define BN_MP_CLEAR_C
#define BN_MP_MONTGOMERY_SETUP_C
#define BN_FAST_MP_MONTGOMERY_REDUCE_C
#define BN_MP_MONTGOMERY_REDUCE_C
#define BN_MP_DR_SETUP_C
#define BN_MP_DR_REDUCE_C
#define BN_MP_REDUCE_2K_SETUP_C
#define BN_MP_REDUCE_2K_C
#define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
#define BN_MP_MULMOD_C
#define BN_MP_SET_C
#define BN_MP_MOD_C
#define BN_MP_COPY_C
#define BN_MP_SQR_C
#define BN_MP_MUL_C
#define BN_MP_EXCH_C
#endif
#if defined(BN_MP_EXTEUCLID_C)
#define BN_MP_INIT_MULTI_C
#define BN_MP_SET_C
#define BN_MP_COPY_C
#define BN_MP_ISZERO_C
#define BN_MP_DIV_C
#define BN_MP_MUL_C
#define BN_MP_SUB_C
#define BN_MP_NEG_C
#define BN_MP_EXCH_C
#define BN_MP_CLEAR_MULTI_C
#endif
#if defined(BN_MP_FREAD_C)
#define BN_MP_ZERO_C
#define BN_MP_S_RMAP_C
#define BN_MP_MUL_D_C
#define BN_MP_ADD_D_C
#define BN_MP_CMP_D_C
#endif
#if defined(BN_MP_FWRITE_C)
#define BN_MP_RADIX_SIZE_C
#define BN_MP_TORADIX_C
#endif
#if defined(BN_MP_GCD_C)
#define BN_MP_ISZERO_C
#define BN_MP_ABS_C
#define BN_MP_INIT_COPY_C
#define BN_MP_CNT_LSB_C
#define BN_MP_DIV_2D_C
#define BN_MP_CMP_MAG_C
#define BN_MP_EXCH_C
#define BN_S_MP_SUB_C
#define BN_MP_MUL_2D_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_GET_INT_C)
#endif
#if defined(BN_MP_GET_LONG_C)
#endif
#if defined(BN_MP_GET_LONG_LONG_C)
#endif
#if defined(BN_MP_GROW_C)
#endif
#if defined(BN_MP_IMPORT_C)
#define BN_MP_ZERO_C
#define BN_MP_MUL_2D_C
#define BN_MP_CLAMP_C
#endif
#if defined(BN_MP_INIT_C)
#endif
#if defined(BN_MP_INIT_COPY_C)
#define BN_MP_INIT_SIZE_C
#define BN_MP_COPY_C
#endif
#if defined(BN_MP_INIT_MULTI_C)
#define BN_MP_ERR_C
#define BN_MP_INIT_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_INIT_SET_C)
#define BN_MP_INIT_C
#define BN_MP_SET_C
#endif
#if defined(BN_MP_INIT_SET_INT_C)
#define BN_MP_INIT_C
#define BN_MP_SET_INT_C
#endif
#if defined(BN_MP_INIT_SIZE_C)
#define BN_MP_INIT_C
#endif
#if defined(BN_MP_INVMOD_C)
#define BN_MP_ISZERO_C
#define BN_MP_ISODD_C
#define BN_FAST_MP_INVMOD_C
#define BN_MP_INVMOD_SLOW_C
#endif
#if defined(BN_MP_INVMOD_SLOW_C)
#define BN_MP_ISZERO_C
#define BN_MP_INIT_MULTI_C
#define BN_MP_MOD_C
#define BN_MP_COPY_C
#define BN_MP_ISEVEN_C
#define BN_MP_SET_C
#define BN_MP_DIV_2_C
#define BN_MP_ISODD_C
#define BN_MP_ADD_C
#define BN_MP_SUB_C
#define BN_MP_CMP_C
#define BN_MP_CMP_D_C
#define BN_MP_CMP_MAG_C
#define BN_MP_EXCH_C
#define BN_MP_CLEAR_MULTI_C
#endif
#if defined(BN_MP_IS_SQUARE_C)
#define BN_MP_MOD_D_C
#define BN_MP_INIT_SET_INT_C
#define BN_MP_MOD_C
#define BN_MP_GET_INT_C
#define BN_MP_SQRT_C
#define BN_MP_SQR_C
#define BN_MP_CMP_MAG_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_JACOBI_C)
#define BN_MP_CMP_D_C
#define BN_MP_ISZERO_C
#define BN_MP_INIT_COPY_C
#define BN_MP_CNT_LSB_C
#define BN_MP_DIV_2D_C
#define BN_MP_MOD_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_KARATSUBA_MUL_C)
#define BN_MP_MUL_C
#define BN_MP_INIT_SIZE_C
#define BN_MP_CLAMP_C
#define BN_S_MP_ADD_C
#define BN_MP_ADD_C
#define BN_S_MP_SUB_C
#define BN_MP_LSHD_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_KARATSUBA_SQR_C)
#define BN_MP_INIT_SIZE_C
#define BN_MP_CLAMP_C
#define BN_MP_SQR_C
#define BN_S_MP_ADD_C
#define BN_S_MP_SUB_C
#define BN_MP_LSHD_C
#define BN_MP_ADD_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_LCM_C)
#define BN_MP_INIT_MULTI_C
#define BN_MP_GCD_C
#define BN_MP_CMP_MAG_C
#define BN_MP_DIV_C
#define BN_MP_MUL_C
#define BN_MP_CLEAR_MULTI_C
#endif
#if defined(BN_MP_LSHD_C)
#define BN_MP_GROW_C
#define BN_MP_RSHD_C
#endif
#if defined(BN_MP_MOD_C)
#define BN_MP_INIT_C
#define BN_MP_DIV_C
#define BN_MP_CLEAR_C
#define BN_MP_ISZERO_C
#define BN_MP_EXCH_C
#define BN_MP_ADD_C
#endif
#if defined(BN_MP_MOD_2D_C)
#define BN_MP_ZERO_C
#define BN_MP_COPY_C
#define BN_MP_CLAMP_C
#endif
#if defined(BN_MP_MOD_D_C)
#define BN_MP_DIV_D_C
#endif
#if defined(BN_MP_MONTGOMERY_CALC_NORMALIZATION_C)
#define BN_MP_COUNT_BITS_C
#define BN_MP_2EXPT_C
#define BN_MP_SET_C
#define BN_MP_MUL_2_C
#define BN_MP_CMP_MAG_C
#define BN_S_MP_SUB_C
#endif
#if defined(BN_MP_MONTGOMERY_REDUCE_C)
#define BN_FAST_MP_MONTGOMERY_REDUCE_C
#define BN_MP_GROW_C
#define BN_MP_CLAMP_C
#define BN_MP_RSHD_C
#define BN_MP_CMP_MAG_C
#define BN_S_MP_SUB_C
#endif
#if defined(BN_MP_MONTGOMERY_SETUP_C)
#endif
#if defined(BN_MP_MUL_C)
#define BN_MP_TOOM_MUL_C
#define BN_MP_KARATSUBA_MUL_C
#define BN_FAST_S_MP_MUL_DIGS_C
#define BN_S_MP_MUL_C
#define BN_S_MP_MUL_DIGS_C
#endif
#if defined(BN_MP_MUL_2_C)
#define BN_MP_GROW_C
#endif
#if defined(BN_MP_MUL_2D_C)
#define BN_MP_COPY_C
#define BN_MP_GROW_C
#define BN_MP_LSHD_C
#define BN_MP_CLAMP_C
#endif
#if defined(BN_MP_MUL_D_C)
#define BN_MP_GROW_C
#define BN_MP_CLAMP_C
#endif
#if defined(BN_MP_MULMOD_C)
#define BN_MP_INIT_C
#define BN_MP_MUL_C
#define BN_MP_CLEAR_C
#define BN_MP_MOD_C
#endif
#if defined(BN_MP_N_ROOT_C)
#define BN_MP_N_ROOT_EX_C
#endif
#if defined(BN_MP_N_ROOT_EX_C)
#define BN_MP_INIT_C
#define BN_MP_SET_C
#define BN_MP_COPY_C
#define BN_MP_EXPT_D_EX_C
#define BN_MP_MUL_C
#define BN_MP_SUB_C
#define BN_MP_MUL_D_C
#define BN_MP_DIV_C
#define BN_MP_CMP_C
#define BN_MP_SUB_D_C
#define BN_MP_EXCH_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_NEG_C)
#define BN_MP_COPY_C
#define BN_MP_ISZERO_C
#endif
#if defined(BN_MP_OR_C)
#define BN_MP_INIT_COPY_C
#define BN_MP_CLAMP_C
#define BN_MP_EXCH_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_PRIME_FERMAT_C)
#define BN_MP_CMP_D_C
#define BN_MP_INIT_C
#define BN_MP_EXPTMOD_C
#define BN_MP_CMP_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_PRIME_IS_DIVISIBLE_C)
#define BN_MP_MOD_D_C
#endif
#if defined(BN_MP_PRIME_IS_PRIME_C)
#define BN_MP_CMP_D_C
#define BN_MP_PRIME_IS_DIVISIBLE_C
#define BN_MP_INIT_C
#define BN_MP_SET_C
#define BN_MP_PRIME_MILLER_RABIN_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_PRIME_MILLER_RABIN_C)
#define BN_MP_CMP_D_C
#define BN_MP_INIT_COPY_C
#define BN_MP_SUB_D_C
#define BN_MP_CNT_LSB_C
#define BN_MP_DIV_2D_C
#define BN_MP_EXPTMOD_C
#define BN_MP_CMP_C
#define BN_MP_SQRMOD_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_PRIME_NEXT_PRIME_C)
#define BN_MP_CMP_D_C
#define BN_MP_SET_C
#define BN_MP_SUB_D_C
#define BN_MP_ISEVEN_C
#define BN_MP_MOD_D_C
#define BN_MP_INIT_C
#define BN_MP_ADD_D_C
#define BN_MP_PRIME_MILLER_RABIN_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_PRIME_RABIN_MILLER_TRIALS_C)
#endif
#if defined(BN_MP_PRIME_RANDOM_EX_C)
#define BN_MP_READ_UNSIGNED_BIN_C
#define BN_MP_PRIME_IS_PRIME_C
#define BN_MP_SUB_D_C
#define BN_MP_DIV_2_C
#define BN_MP_MUL_2_C
#define BN_MP_ADD_D_C
#endif
#if defined(BN_MP_RADIX_SIZE_C)
#define BN_MP_ISZERO_C
#define BN_MP_COUNT_BITS_C
#define BN_MP_INIT_COPY_C
#define BN_MP_DIV_D_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_RADIX_SMAP_C)
#define BN_MP_S_RMAP_C
#endif
#if defined(BN_MP_RAND_C)
#define BN_MP_ZERO_C
#define BN_MP_ADD_D_C
#define BN_MP_LSHD_C
#endif
#if defined(BN_MP_READ_RADIX_C)
#define BN_MP_ZERO_C
#define BN_MP_S_RMAP_C
#define BN_MP_MUL_D_C
#define BN_MP_ADD_D_C
#define BN_MP_ISZERO_C
#endif
#if defined(BN_MP_READ_SIGNED_BIN_C)
#define BN_MP_READ_UNSIGNED_BIN_C
#endif
#if defined(BN_MP_READ_UNSIGNED_BIN_C)
#define BN_MP_GROW_C
#define BN_MP_ZERO_C
#define BN_MP_MUL_2D_C
#define BN_MP_CLAMP_C
#endif
#if defined(BN_MP_REDUCE_C)
#define BN_MP_REDUCE_SETUP_C
#define BN_MP_INIT_COPY_C
#define BN_MP_RSHD_C
#define BN_MP_MUL_C
#define BN_S_MP_MUL_HIGH_DIGS_C
#define BN_FAST_S_MP_MUL_HIGH_DIGS_C
#define BN_MP_MOD_2D_C
#define BN_S_MP_MUL_DIGS_C
#define BN_MP_SUB_C
#define BN_MP_CMP_D_C
#define BN_MP_SET_C
#define BN_MP_LSHD_C
#define BN_MP_ADD_C
#define BN_MP_CMP_C
#define BN_S_MP_SUB_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_REDUCE_2K_C)
#define BN_MP_INIT_C
#define BN_MP_COUNT_BITS_C
#define BN_MP_DIV_2D_C
#define BN_MP_MUL_D_C
#define BN_S_MP_ADD_C
#define BN_MP_CMP_MAG_C
#define BN_S_MP_SUB_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_REDUCE_2K_L_C)
#define BN_MP_INIT_C
#define BN_MP_COUNT_BITS_C
#define BN_MP_DIV_2D_C
#define BN_MP_MUL_C
#define BN_S_MP_ADD_C
#define BN_MP_CMP_MAG_C
#define BN_S_MP_SUB_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_REDUCE_2K_SETUP_C)
#define BN_MP_INIT_C
#define BN_MP_COUNT_BITS_C
#define BN_MP_2EXPT_C
#define BN_MP_CLEAR_C
#define BN_S_MP_SUB_C
#endif
#if defined(BN_MP_REDUCE_2K_SETUP_L_C)
#define BN_MP_INIT_C
#define BN_MP_2EXPT_C
#define BN_MP_COUNT_BITS_C
#define BN_S_MP_SUB_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_REDUCE_IS_2K_C)
#define BN_MP_REDUCE_2K_C
#define BN_MP_COUNT_BITS_C
#endif
#if defined(BN_MP_REDUCE_IS_2K_L_C)
#endif
#if defined(BN_MP_REDUCE_SETUP_C)
#define BN_MP_2EXPT_C
#define BN_MP_DIV_C
#endif
#if defined(BN_MP_RSHD_C)
#define BN_MP_ZERO_C
#endif
#if defined(BN_MP_SET_C)
#define BN_MP_ZERO_C
#endif
#if defined(BN_MP_SET_INT_C)
#define BN_MP_ZERO_C
#define BN_MP_MUL_2D_C
#define BN_MP_CLAMP_C
#endif
#if defined(BN_MP_SET_LONG_C)
#endif
#if defined(BN_MP_SET_LONG_LONG_C)
#endif
#if defined(BN_MP_SHRINK_C)
#endif
#if defined(BN_MP_SIGNED_BIN_SIZE_C)
#define BN_MP_UNSIGNED_BIN_SIZE_C
#endif
#if defined(BN_MP_SQR_C)
#define BN_MP_TOOM_SQR_C
#define BN_MP_KARATSUBA_SQR_C
#define BN_FAST_S_MP_SQR_C
#define BN_S_MP_SQR_C
#endif
#if defined(BN_MP_SQRMOD_C)
#define BN_MP_INIT_C
#define BN_MP_SQR_C
#define BN_MP_CLEAR_C
#define BN_MP_MOD_C
#endif
#if defined(BN_MP_SQRT_C)
#define BN_MP_N_ROOT_C
#define BN_MP_ISZERO_C
#define BN_MP_ZERO_C
#define BN_MP_INIT_COPY_C
#define BN_MP_RSHD_C
#define BN_MP_DIV_C
#define BN_MP_ADD_C
#define BN_MP_DIV_2_C
#define BN_MP_CMP_MAG_C
#define BN_MP_EXCH_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_SQRTMOD_PRIME_C)
#define BN_MP_CMP_D_C
#define BN_MP_ZERO_C
#define BN_MP_JACOBI_C
#define BN_MP_INIT_MULTI_C
#define BN_MP_MOD_D_C
#define BN_MP_ADD_D_C
#define BN_MP_DIV_2_C
#define BN_MP_EXPTMOD_C
#define BN_MP_COPY_C
#define BN_MP_SUB_D_C
#define BN_MP_ISEVEN_C
#define BN_MP_SET_INT_C
#define BN_MP_SQRMOD_C
#define BN_MP_MULMOD_C
#define BN_MP_SET_C
#define BN_MP_CLEAR_MULTI_C
#endif
#if defined(BN_MP_SUB_C)
#define BN_S_MP_ADD_C
#define BN_MP_CMP_MAG_C
#define BN_S_MP_SUB_C
#endif
#if defined(BN_MP_SUB_D_C)
#define BN_MP_GROW_C
#define BN_MP_ADD_D_C
#define BN_MP_CLAMP_C
#endif
#if defined(BN_MP_SUBMOD_C)
#define BN_MP_INIT_C
#define BN_MP_SUB_C
#define BN_MP_CLEAR_C
#define BN_MP_MOD_C
#endif
#if defined(BN_MP_TO_SIGNED_BIN_C)
#define BN_MP_TO_UNSIGNED_BIN_C
#endif
#if defined(BN_MP_TO_SIGNED_BIN_N_C)
#define BN_MP_SIGNED_BIN_SIZE_C
#define BN_MP_TO_SIGNED_BIN_C
#endif
#if defined(BN_MP_TO_UNSIGNED_BIN_C)
#define BN_MP_INIT_COPY_C
#define BN_MP_ISZERO_C
#define BN_MP_DIV_2D_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_TO_UNSIGNED_BIN_N_C)
#define BN_MP_UNSIGNED_BIN_SIZE_C
#define BN_MP_TO_UNSIGNED_BIN_C
#endif
#if defined(BN_MP_TOOM_MUL_C)
#define BN_MP_INIT_MULTI_C
#define BN_MP_MOD_2D_C
#define BN_MP_COPY_C
#define BN_MP_RSHD_C
#define BN_MP_MUL_C
#define BN_MP_MUL_2_C
#define BN_MP_ADD_C
#define BN_MP_SUB_C
#define BN_MP_DIV_2_C
#define BN_MP_MUL_2D_C
#define BN_MP_MUL_D_C
#define BN_MP_DIV_3_C
#define BN_MP_LSHD_C
#define BN_MP_CLEAR_MULTI_C
#endif
#if defined(BN_MP_TOOM_SQR_C)
#define BN_MP_INIT_MULTI_C
#define BN_MP_MOD_2D_C
#define BN_MP_COPY_C
#define BN_MP_RSHD_C
#define BN_MP_SQR_C
#define BN_MP_MUL_2_C
#define BN_MP_ADD_C
#define BN_MP_SUB_C
#define BN_MP_DIV_2_C
#define BN_MP_MUL_2D_C
#define BN_MP_MUL_D_C
#define BN_MP_DIV_3_C
#define BN_MP_LSHD_C
#define BN_MP_CLEAR_MULTI_C
#endif
#if defined(BN_MP_TORADIX_C)
#define BN_MP_ISZERO_C
#define BN_MP_INIT_COPY_C
#define BN_MP_DIV_D_C
#define BN_MP_CLEAR_C
#define BN_MP_S_RMAP_C
#endif
#if defined(BN_MP_TORADIX_N_C)
#define BN_MP_ISZERO_C
#define BN_MP_INIT_COPY_C
#define BN_MP_DIV_D_C
#define BN_MP_CLEAR_C
#define BN_MP_S_RMAP_C
#endif
#if defined(BN_MP_UNSIGNED_BIN_SIZE_C)
#define BN_MP_COUNT_BITS_C
#endif
#if defined(BN_MP_XOR_C)
#define BN_MP_INIT_COPY_C
#define BN_MP_CLAMP_C
#define BN_MP_EXCH_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_ZERO_C)
#endif
#if defined(BN_PRIME_TAB_C)
#endif
#if defined(BN_REVERSE_C)
#endif
#if defined(BN_S_MP_ADD_C)
#define BN_MP_GROW_C
#define BN_MP_CLAMP_C
#endif
#if defined(BN_S_MP_EXPTMOD_C)
#define BN_MP_COUNT_BITS_C
#define BN_MP_INIT_C
#define BN_MP_CLEAR_C
#define BN_MP_REDUCE_SETUP_C
#define BN_MP_REDUCE_C
#define BN_MP_REDUCE_2K_SETUP_L_C
#define BN_MP_REDUCE_2K_L_C
#define BN_MP_MOD_C
#define BN_MP_COPY_C
#define BN_MP_SQR_C
#define BN_MP_MUL_C
#define BN_MP_SET_C
#define BN_MP_EXCH_C
#endif
#if defined(BN_S_MP_MUL_DIGS_C)
#define BN_FAST_S_MP_MUL_DIGS_C
#define BN_MP_INIT_SIZE_C
#define BN_MP_CLAMP_C
#define BN_MP_EXCH_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_S_MP_MUL_HIGH_DIGS_C)
#define BN_FAST_S_MP_MUL_HIGH_DIGS_C
#define BN_MP_INIT_SIZE_C
#define BN_MP_CLAMP_C
#define BN_MP_EXCH_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_S_MP_SQR_C)
#define BN_MP_INIT_SIZE_C
#define BN_MP_CLAMP_C
#define BN_MP_EXCH_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_S_MP_SUB_C)
#define BN_MP_GROW_C
#define BN_MP_CLAMP_C
#endif
#if defined(BNCORE_C)
#endif
#ifdef LTM3
#define LTM_LAST
#endif
/* super class file for PK algos */
/* default ... include all MPI */
#define LTM_ALL
/* RSA only (does not support DH/DSA/ECC) */
/* #define SC_RSA_1 */
/* For reference.... On an Athlon64 optimizing for speed...
LTM's mpi.o with all functions [striped] is 142KiB in size.
*/
/* Works for RSA only, mpi.o is 68KiB */
#ifdef SC_RSA_1
#define BN_MP_SHRINK_C
#define BN_MP_LCM_C
#define BN_MP_PRIME_RANDOM_EX_C
#define BN_MP_INVMOD_C
#define BN_MP_GCD_C
#define BN_MP_MOD_C
#define BN_MP_MULMOD_C
#define BN_MP_ADDMOD_C
#define BN_MP_EXPTMOD_C
#define BN_MP_SET_INT_C
#define BN_MP_INIT_MULTI_C
#define BN_MP_CLEAR_MULTI_C
#define BN_MP_UNSIGNED_BIN_SIZE_C
#define BN_MP_TO_UNSIGNED_BIN_C
#define BN_MP_MOD_D_C
#define BN_MP_PRIME_RABIN_MILLER_TRIALS_C
#define BN_REVERSE_C
#define BN_PRIME_TAB_C
/* other modifiers */
#define BN_MP_DIV_SMALL /* Slower division, not critical */
/* here we are on the last pass so we turn things off. The functions classes are still there
* but we remove them specifically from the build. This also invokes tweaks in functions
* like removing support for even moduli, etc...
*/
#ifdef LTM_LAST
#undef BN_MP_TOOM_MUL_C
#undef BN_MP_TOOM_SQR_C
#undef BN_MP_KARATSUBA_MUL_C
#undef BN_MP_KARATSUBA_SQR_C
#undef BN_MP_REDUCE_C
#undef BN_MP_REDUCE_SETUP_C
#undef BN_MP_DR_IS_MODULUS_C
#undef BN_MP_DR_SETUP_C
#undef BN_MP_DR_REDUCE_C
#undef BN_MP_REDUCE_IS_2K_C
#undef BN_MP_REDUCE_2K_SETUP_C
#undef BN_MP_REDUCE_2K_C
#undef BN_S_MP_EXPTMOD_C
#undef BN_MP_DIV_3_C
#undef BN_S_MP_MUL_HIGH_DIGS_C
#undef BN_FAST_S_MP_MUL_HIGH_DIGS_C
#undef BN_FAST_MP_INVMOD_C
/* To safely undefine these you have to make sure your RSA key won't exceed the Comba threshold
* which is roughly 255 digits [7140 bits for 32-bit machines, 15300 bits for 64-bit machines]
* which means roughly speaking you can handle upto 2536-bit RSA keys with these defined without
* trouble.
*/
#undef BN_S_MP_MUL_DIGS_C
#undef BN_S_MP_SQR_C
#undef BN_MP_MONTGOMERY_REDUCE_C
#endif
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
#if !(defined(LTM1) && defined(LTM2) && defined(LTM3))
#if defined(LTM2)
#define LTM3
#endif
#if defined(LTM1)
#define LTM2
#endif
#define LTM1
#if defined(LTM_ALL)
#define BN_ERROR_C
#define BN_FAST_MP_INVMOD_C
#define BN_FAST_MP_MONTGOMERY_REDUCE_C
#define BN_FAST_S_MP_MUL_DIGS_C
#define BN_FAST_S_MP_MUL_HIGH_DIGS_C
#define BN_FAST_S_MP_SQR_C
#define BN_MP_2EXPT_C
#define BN_MP_ABS_C
#define BN_MP_ADD_C
#define BN_MP_ADD_D_C
#define BN_MP_ADDMOD_C
#define BN_MP_AND_C
#define BN_MP_CLAMP_C
#define BN_MP_CLEAR_C
#define BN_MP_CLEAR_MULTI_C
#define BN_MP_CMP_C
#define BN_MP_CMP_D_C
#define BN_MP_CMP_MAG_C
#define BN_MP_CNT_LSB_C
#define BN_MP_COPY_C
#define BN_MP_COUNT_BITS_C
#define BN_MP_DIV_C
#define BN_MP_DIV_2_C
#define BN_MP_DIV_2D_C
#define BN_MP_DIV_3_C
#define BN_MP_DIV_D_C
#define BN_MP_DR_IS_MODULUS_C
#define BN_MP_DR_REDUCE_C
#define BN_MP_DR_SETUP_C
#define BN_MP_EXCH_C
#define BN_MP_EXPORT_C
#define BN_MP_EXPT_D_C
#define BN_MP_EXPT_D_EX_C
#define BN_MP_EXPTMOD_C
#define BN_MP_EXPTMOD_FAST_C
#define BN_MP_EXTEUCLID_C
#define BN_MP_FREAD_C
#define BN_MP_FWRITE_C
#define BN_MP_GCD_C
#define BN_MP_GET_INT_C
#define BN_MP_GET_LONG_C
#define BN_MP_GET_LONG_LONG_C
#define BN_MP_GROW_C
#define BN_MP_IMPORT_C
#define BN_MP_INIT_C
#define BN_MP_INIT_COPY_C
#define BN_MP_INIT_MULTI_C
#define BN_MP_INIT_SET_C
#define BN_MP_INIT_SET_INT_C
#define BN_MP_INIT_SIZE_C
#define BN_MP_INVMOD_C
#define BN_MP_INVMOD_SLOW_C
#define BN_MP_IS_SQUARE_C
#define BN_MP_JACOBI_C
#define BN_MP_KARATSUBA_MUL_C
#define BN_MP_KARATSUBA_SQR_C
#define BN_MP_LCM_C
#define BN_MP_LSHD_C
#define BN_MP_MOD_C
#define BN_MP_MOD_2D_C
#define BN_MP_MOD_D_C
#define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
#define BN_MP_MONTGOMERY_REDUCE_C
#define BN_MP_MONTGOMERY_SETUP_C
#define BN_MP_MUL_C
#define BN_MP_MUL_2_C
#define BN_MP_MUL_2D_C
#define BN_MP_MUL_D_C
#define BN_MP_MULMOD_C
#define BN_MP_N_ROOT_C
#define BN_MP_N_ROOT_EX_C
#define BN_MP_NEG_C
#define BN_MP_OR_C
#define BN_MP_PRIME_FERMAT_C
#define BN_MP_PRIME_IS_DIVISIBLE_C
#define BN_MP_PRIME_IS_PRIME_C
#define BN_MP_PRIME_MILLER_RABIN_C
#define BN_MP_PRIME_NEXT_PRIME_C
#define BN_MP_PRIME_RABIN_MILLER_TRIALS_C
#define BN_MP_PRIME_RANDOM_EX_C
#define BN_MP_RADIX_SIZE_C
#define BN_MP_RADIX_SMAP_C
#define BN_MP_RAND_C
#define BN_MP_READ_RADIX_C
#define BN_MP_READ_SIGNED_BIN_C
#define BN_MP_READ_UNSIGNED_BIN_C
#define BN_MP_REDUCE_C
#define BN_MP_REDUCE_2K_C
#define BN_MP_REDUCE_2K_L_C
#define BN_MP_REDUCE_2K_SETUP_C
#define BN_MP_REDUCE_2K_SETUP_L_C
#define BN_MP_REDUCE_IS_2K_C
#define BN_MP_REDUCE_IS_2K_L_C
#define BN_MP_REDUCE_SETUP_C
#define BN_MP_RSHD_C
#define BN_MP_SET_C
#define BN_MP_SET_INT_C
#define BN_MP_SET_LONG_C
#define BN_MP_SET_LONG_LONG_C
#define BN_MP_SHRINK_C
#define BN_MP_SIGNED_BIN_SIZE_C
#define BN_MP_SQR_C
#define BN_MP_SQRMOD_C
#define BN_MP_SQRT_C
#define BN_MP_SQRTMOD_PRIME_C
#define BN_MP_SUB_C
#define BN_MP_SUB_D_C
#define BN_MP_SUBMOD_C
#define BN_MP_TO_SIGNED_BIN_C
#define BN_MP_TO_SIGNED_BIN_N_C
#define BN_MP_TO_UNSIGNED_BIN_C
#define BN_MP_TO_UNSIGNED_BIN_N_C
#define BN_MP_TOOM_MUL_C
#define BN_MP_TOOM_SQR_C
#define BN_MP_TORADIX_C
#define BN_MP_TORADIX_N_C
#define BN_MP_UNSIGNED_BIN_SIZE_C
#define BN_MP_XOR_C
#define BN_MP_ZERO_C
#define BN_PRIME_TAB_C
#define BN_REVERSE_C
#define BN_S_MP_ADD_C
#define BN_S_MP_EXPTMOD_C
#define BN_S_MP_MUL_DIGS_C
#define BN_S_MP_MUL_HIGH_DIGS_C
#define BN_S_MP_SQR_C
#define BN_S_MP_SUB_C
#define BNCORE_C
#endif
#if defined(BN_ERROR_C)
#define BN_MP_ERROR_TO_STRING_C
#endif
#if defined(BN_FAST_MP_INVMOD_C)
#define BN_MP_ISEVEN_C
#define BN_MP_INIT_MULTI_C
#define BN_MP_COPY_C
#define BN_MP_MOD_C
#define BN_MP_SET_C
#define BN_MP_DIV_2_C
#define BN_MP_ISODD_C
#define BN_MP_SUB_C
#define BN_MP_CMP_C
#define BN_MP_ISZERO_C
#define BN_MP_CMP_D_C
#define BN_MP_ADD_C
#define BN_MP_EXCH_C
#define BN_MP_CLEAR_MULTI_C
#endif
#if defined(BN_FAST_MP_MONTGOMERY_REDUCE_C)
#define BN_MP_GROW_C
#define BN_MP_RSHD_C
#define BN_MP_CLAMP_C
#define BN_MP_CMP_MAG_C
#define BN_S_MP_SUB_C
#endif
#if defined(BN_FAST_S_MP_MUL_DIGS_C)
#define BN_MP_GROW_C
#define BN_MP_CLAMP_C
#endif
#if defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C)
#define BN_MP_GROW_C
#define BN_MP_CLAMP_C
#endif
#if defined(BN_FAST_S_MP_SQR_C)
#define BN_MP_GROW_C
#define BN_MP_CLAMP_C
#endif
#if defined(BN_MP_2EXPT_C)
#define BN_MP_ZERO_C
#define BN_MP_GROW_C
#endif
#if defined(BN_MP_ABS_C)
#define BN_MP_COPY_C
#endif
#if defined(BN_MP_ADD_C)
#define BN_S_MP_ADD_C
#define BN_MP_CMP_MAG_C
#define BN_S_MP_SUB_C
#endif
#if defined(BN_MP_ADD_D_C)
#define BN_MP_GROW_C
#define BN_MP_SUB_D_C
#define BN_MP_CLAMP_C
#endif
#if defined(BN_MP_ADDMOD_C)
#define BN_MP_INIT_C
#define BN_MP_ADD_C
#define BN_MP_CLEAR_C
#define BN_MP_MOD_C
#endif
#if defined(BN_MP_AND_C)
#define BN_MP_INIT_COPY_C
#define BN_MP_CLAMP_C
#define BN_MP_EXCH_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_CLAMP_C)
#endif
#if defined(BN_MP_CLEAR_C)
#endif
#if defined(BN_MP_CLEAR_MULTI_C)
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_CMP_C)
#define BN_MP_CMP_MAG_C
#endif
#if defined(BN_MP_CMP_D_C)
#endif
#if defined(BN_MP_CMP_MAG_C)
#endif
#if defined(BN_MP_CNT_LSB_C)
#define BN_MP_ISZERO_C
#endif
#if defined(BN_MP_COPY_C)
#define BN_MP_GROW_C
#endif
#if defined(BN_MP_COUNT_BITS_C)
#endif
#if defined(BN_MP_DIV_C)
#define BN_MP_ISZERO_C
#define BN_MP_CMP_MAG_C
#define BN_MP_COPY_C
#define BN_MP_ZERO_C
#define BN_MP_INIT_MULTI_C
#define BN_MP_SET_C
#define BN_MP_COUNT_BITS_C
#define BN_MP_ABS_C
#define BN_MP_MUL_2D_C
#define BN_MP_CMP_C
#define BN_MP_SUB_C
#define BN_MP_ADD_C
#define BN_MP_DIV_2D_C
#define BN_MP_EXCH_C
#define BN_MP_CLEAR_MULTI_C
#define BN_MP_INIT_SIZE_C
#define BN_MP_INIT_C
#define BN_MP_INIT_COPY_C
#define BN_MP_LSHD_C
#define BN_MP_RSHD_C
#define BN_MP_MUL_D_C
#define BN_MP_CLAMP_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_DIV_2_C)
#define BN_MP_GROW_C
#define BN_MP_CLAMP_C
#endif
#if defined(BN_MP_DIV_2D_C)
#define BN_MP_COPY_C
#define BN_MP_ZERO_C
#define BN_MP_INIT_C
#define BN_MP_MOD_2D_C
#define BN_MP_CLEAR_C
#define BN_MP_RSHD_C
#define BN_MP_CLAMP_C
#define BN_MP_EXCH_C
#endif
#if defined(BN_MP_DIV_3_C)
#define BN_MP_INIT_SIZE_C
#define BN_MP_CLAMP_C
#define BN_MP_EXCH_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_DIV_D_C)
#define BN_MP_ISZERO_C
#define BN_MP_COPY_C
#define BN_MP_DIV_2D_C
#define BN_MP_DIV_3_C
#define BN_MP_INIT_SIZE_C
#define BN_MP_CLAMP_C
#define BN_MP_EXCH_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_DR_IS_MODULUS_C)
#endif
#if defined(BN_MP_DR_REDUCE_C)
#define BN_MP_GROW_C
#define BN_MP_CLAMP_C
#define BN_MP_CMP_MAG_C
#define BN_S_MP_SUB_C
#endif
#if defined(BN_MP_DR_SETUP_C)
#endif
#if defined(BN_MP_EXCH_C)
#endif
#if defined(BN_MP_EXPORT_C)
#define BN_MP_INIT_COPY_C
#define BN_MP_COUNT_BITS_C
#define BN_MP_DIV_2D_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_EXPT_D_C)
#define BN_MP_EXPT_D_EX_C
#endif
#if defined(BN_MP_EXPT_D_EX_C)
#define BN_MP_INIT_COPY_C
#define BN_MP_SET_C
#define BN_MP_MUL_C
#define BN_MP_CLEAR_C
#define BN_MP_SQR_C
#endif
#if defined(BN_MP_EXPTMOD_C)
#define BN_MP_INIT_C
#define BN_MP_INVMOD_C
#define BN_MP_CLEAR_C
#define BN_MP_ABS_C
#define BN_MP_CLEAR_MULTI_C
#define BN_MP_REDUCE_IS_2K_L_C
#define BN_S_MP_EXPTMOD_C
#define BN_MP_DR_IS_MODULUS_C
#define BN_MP_REDUCE_IS_2K_C
#define BN_MP_ISODD_C
#define BN_MP_EXPTMOD_FAST_C
#endif
#if defined(BN_MP_EXPTMOD_FAST_C)
#define BN_MP_COUNT_BITS_C
#define BN_MP_INIT_C
#define BN_MP_CLEAR_C
#define BN_MP_MONTGOMERY_SETUP_C
#define BN_FAST_MP_MONTGOMERY_REDUCE_C
#define BN_MP_MONTGOMERY_REDUCE_C
#define BN_MP_DR_SETUP_C
#define BN_MP_DR_REDUCE_C
#define BN_MP_REDUCE_2K_SETUP_C
#define BN_MP_REDUCE_2K_C
#define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
#define BN_MP_MULMOD_C
#define BN_MP_SET_C
#define BN_MP_MOD_C
#define BN_MP_COPY_C
#define BN_MP_SQR_C
#define BN_MP_MUL_C
#define BN_MP_EXCH_C
#endif
#if defined(BN_MP_EXTEUCLID_C)
#define BN_MP_INIT_MULTI_C
#define BN_MP_SET_C
#define BN_MP_COPY_C
#define BN_MP_ISZERO_C
#define BN_MP_DIV_C
#define BN_MP_MUL_C
#define BN_MP_SUB_C
#define BN_MP_NEG_C
#define BN_MP_EXCH_C
#define BN_MP_CLEAR_MULTI_C
#endif
#if defined(BN_MP_FREAD_C)
#define BN_MP_ZERO_C
#define BN_MP_S_RMAP_C
#define BN_MP_MUL_D_C
#define BN_MP_ADD_D_C
#define BN_MP_CMP_D_C
#endif
#if defined(BN_MP_FWRITE_C)
#define BN_MP_RADIX_SIZE_C
#define BN_MP_TORADIX_C
#endif
#if defined(BN_MP_GCD_C)
#define BN_MP_ISZERO_C
#define BN_MP_ABS_C
#define BN_MP_INIT_COPY_C
#define BN_MP_CNT_LSB_C
#define BN_MP_DIV_2D_C
#define BN_MP_CMP_MAG_C
#define BN_MP_EXCH_C
#define BN_S_MP_SUB_C
#define BN_MP_MUL_2D_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_GET_INT_C)
#endif
#if defined(BN_MP_GET_LONG_C)
#endif
#if defined(BN_MP_GET_LONG_LONG_C)
#endif
#if defined(BN_MP_GROW_C)
#endif
#if defined(BN_MP_IMPORT_C)
#define BN_MP_ZERO_C
#define BN_MP_MUL_2D_C
#define BN_MP_CLAMP_C
#endif
#if defined(BN_MP_INIT_C)
#endif
#if defined(BN_MP_INIT_COPY_C)
#define BN_MP_INIT_SIZE_C
#define BN_MP_COPY_C
#endif
#if defined(BN_MP_INIT_MULTI_C)
#define BN_MP_ERR_C
#define BN_MP_INIT_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_INIT_SET_C)
#define BN_MP_INIT_C
#define BN_MP_SET_C
#endif
#if defined(BN_MP_INIT_SET_INT_C)
#define BN_MP_INIT_C
#define BN_MP_SET_INT_C
#endif
#if defined(BN_MP_INIT_SIZE_C)
#define BN_MP_INIT_C
#endif
#if defined(BN_MP_INVMOD_C)
#define BN_MP_ISZERO_C
#define BN_MP_ISODD_C
#define BN_FAST_MP_INVMOD_C
#define BN_MP_INVMOD_SLOW_C
#endif
#if defined(BN_MP_INVMOD_SLOW_C)
#define BN_MP_ISZERO_C
#define BN_MP_INIT_MULTI_C
#define BN_MP_MOD_C
#define BN_MP_COPY_C
#define BN_MP_ISEVEN_C
#define BN_MP_SET_C
#define BN_MP_DIV_2_C
#define BN_MP_ISODD_C
#define BN_MP_ADD_C
#define BN_MP_SUB_C
#define BN_MP_CMP_C
#define BN_MP_CMP_D_C
#define BN_MP_CMP_MAG_C
#define BN_MP_EXCH_C
#define BN_MP_CLEAR_MULTI_C
#endif
#if defined(BN_MP_IS_SQUARE_C)
#define BN_MP_MOD_D_C
#define BN_MP_INIT_SET_INT_C
#define BN_MP_MOD_C
#define BN_MP_GET_INT_C
#define BN_MP_SQRT_C
#define BN_MP_SQR_C
#define BN_MP_CMP_MAG_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_JACOBI_C)
#define BN_MP_CMP_D_C
#define BN_MP_ISZERO_C
#define BN_MP_INIT_COPY_C
#define BN_MP_CNT_LSB_C
#define BN_MP_DIV_2D_C
#define BN_MP_MOD_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_KARATSUBA_MUL_C)
#define BN_MP_MUL_C
#define BN_MP_INIT_SIZE_C
#define BN_MP_CLAMP_C
#define BN_S_MP_ADD_C
#define BN_MP_ADD_C
#define BN_S_MP_SUB_C
#define BN_MP_LSHD_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_KARATSUBA_SQR_C)
#define BN_MP_INIT_SIZE_C
#define BN_MP_CLAMP_C
#define BN_MP_SQR_C
#define BN_S_MP_ADD_C
#define BN_S_MP_SUB_C
#define BN_MP_LSHD_C
#define BN_MP_ADD_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_LCM_C)
#define BN_MP_INIT_MULTI_C
#define BN_MP_GCD_C
#define BN_MP_CMP_MAG_C
#define BN_MP_DIV_C
#define BN_MP_MUL_C
#define BN_MP_CLEAR_MULTI_C
#endif
#if defined(BN_MP_LSHD_C)
#define BN_MP_GROW_C
#define BN_MP_RSHD_C
#endif
#if defined(BN_MP_MOD_C)
#define BN_MP_INIT_C
#define BN_MP_DIV_C
#define BN_MP_CLEAR_C
#define BN_MP_ISZERO_C
#define BN_MP_EXCH_C
#define BN_MP_ADD_C
#endif
#if defined(BN_MP_MOD_2D_C)
#define BN_MP_ZERO_C
#define BN_MP_COPY_C
#define BN_MP_CLAMP_C
#endif
#if defined(BN_MP_MOD_D_C)
#define BN_MP_DIV_D_C
#endif
#if defined(BN_MP_MONTGOMERY_CALC_NORMALIZATION_C)
#define BN_MP_COUNT_BITS_C
#define BN_MP_2EXPT_C
#define BN_MP_SET_C
#define BN_MP_MUL_2_C
#define BN_MP_CMP_MAG_C
#define BN_S_MP_SUB_C
#endif
#if defined(BN_MP_MONTGOMERY_REDUCE_C)
#define BN_FAST_MP_MONTGOMERY_REDUCE_C
#define BN_MP_GROW_C
#define BN_MP_CLAMP_C
#define BN_MP_RSHD_C
#define BN_MP_CMP_MAG_C
#define BN_S_MP_SUB_C
#endif
#if defined(BN_MP_MONTGOMERY_SETUP_C)
#endif
#if defined(BN_MP_MUL_C)
#define BN_MP_TOOM_MUL_C
#define BN_MP_KARATSUBA_MUL_C
#define BN_FAST_S_MP_MUL_DIGS_C
#define BN_S_MP_MUL_C
#define BN_S_MP_MUL_DIGS_C
#endif
#if defined(BN_MP_MUL_2_C)
#define BN_MP_GROW_C
#endif
#if defined(BN_MP_MUL_2D_C)
#define BN_MP_COPY_C
#define BN_MP_GROW_C
#define BN_MP_LSHD_C
#define BN_MP_CLAMP_C
#endif
#if defined(BN_MP_MUL_D_C)
#define BN_MP_GROW_C
#define BN_MP_CLAMP_C
#endif
#if defined(BN_MP_MULMOD_C)
#define BN_MP_INIT_C
#define BN_MP_MUL_C
#define BN_MP_CLEAR_C
#define BN_MP_MOD_C
#endif
#if defined(BN_MP_N_ROOT_C)
#define BN_MP_N_ROOT_EX_C
#endif
#if defined(BN_MP_N_ROOT_EX_C)
#define BN_MP_INIT_C
#define BN_MP_SET_C
#define BN_MP_COPY_C
#define BN_MP_EXPT_D_EX_C
#define BN_MP_MUL_C
#define BN_MP_SUB_C
#define BN_MP_MUL_D_C
#define BN_MP_DIV_C
#define BN_MP_CMP_C
#define BN_MP_SUB_D_C
#define BN_MP_EXCH_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_NEG_C)
#define BN_MP_COPY_C
#define BN_MP_ISZERO_C
#endif
#if defined(BN_MP_OR_C)
#define BN_MP_INIT_COPY_C
#define BN_MP_CLAMP_C
#define BN_MP_EXCH_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_PRIME_FERMAT_C)
#define BN_MP_CMP_D_C
#define BN_MP_INIT_C
#define BN_MP_EXPTMOD_C
#define BN_MP_CMP_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_PRIME_IS_DIVISIBLE_C)
#define BN_MP_MOD_D_C
#endif
#if defined(BN_MP_PRIME_IS_PRIME_C)
#define BN_MP_CMP_D_C
#define BN_MP_PRIME_IS_DIVISIBLE_C
#define BN_MP_INIT_C
#define BN_MP_SET_C
#define BN_MP_PRIME_MILLER_RABIN_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_PRIME_MILLER_RABIN_C)
#define BN_MP_CMP_D_C
#define BN_MP_INIT_COPY_C
#define BN_MP_SUB_D_C
#define BN_MP_CNT_LSB_C
#define BN_MP_DIV_2D_C
#define BN_MP_EXPTMOD_C
#define BN_MP_CMP_C
#define BN_MP_SQRMOD_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_PRIME_NEXT_PRIME_C)
#define BN_MP_CMP_D_C
#define BN_MP_SET_C
#define BN_MP_SUB_D_C
#define BN_MP_ISEVEN_C
#define BN_MP_MOD_D_C
#define BN_MP_INIT_C
#define BN_MP_ADD_D_C
#define BN_MP_PRIME_MILLER_RABIN_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_PRIME_RABIN_MILLER_TRIALS_C)
#endif
#if defined(BN_MP_PRIME_RANDOM_EX_C)
#define BN_MP_READ_UNSIGNED_BIN_C
#define BN_MP_PRIME_IS_PRIME_C
#define BN_MP_SUB_D_C
#define BN_MP_DIV_2_C
#define BN_MP_MUL_2_C
#define BN_MP_ADD_D_C
#endif
#if defined(BN_MP_RADIX_SIZE_C)
#define BN_MP_ISZERO_C
#define BN_MP_COUNT_BITS_C
#define BN_MP_INIT_COPY_C
#define BN_MP_DIV_D_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_RADIX_SMAP_C)
#define BN_MP_S_RMAP_C
#endif
#if defined(BN_MP_RAND_C)
#define BN_MP_ZERO_C
#define BN_MP_ADD_D_C
#define BN_MP_LSHD_C
#endif
#if defined(BN_MP_READ_RADIX_C)
#define BN_MP_ZERO_C
#define BN_MP_S_RMAP_C
#define BN_MP_MUL_D_C
#define BN_MP_ADD_D_C
#define BN_MP_ISZERO_C
#endif
#if defined(BN_MP_READ_SIGNED_BIN_C)
#define BN_MP_READ_UNSIGNED_BIN_C
#endif
#if defined(BN_MP_READ_UNSIGNED_BIN_C)
#define BN_MP_GROW_C
#define BN_MP_ZERO_C
#define BN_MP_MUL_2D_C
#define BN_MP_CLAMP_C
#endif
#if defined(BN_MP_REDUCE_C)
#define BN_MP_REDUCE_SETUP_C
#define BN_MP_INIT_COPY_C
#define BN_MP_RSHD_C
#define BN_MP_MUL_C
#define BN_S_MP_MUL_HIGH_DIGS_C
#define BN_FAST_S_MP_MUL_HIGH_DIGS_C
#define BN_MP_MOD_2D_C
#define BN_S_MP_MUL_DIGS_C
#define BN_MP_SUB_C
#define BN_MP_CMP_D_C
#define BN_MP_SET_C
#define BN_MP_LSHD_C
#define BN_MP_ADD_C
#define BN_MP_CMP_C
#define BN_S_MP_SUB_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_REDUCE_2K_C)
#define BN_MP_INIT_C
#define BN_MP_COUNT_BITS_C
#define BN_MP_DIV_2D_C
#define BN_MP_MUL_D_C
#define BN_S_MP_ADD_C
#define BN_MP_CMP_MAG_C
#define BN_S_MP_SUB_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_REDUCE_2K_L_C)
#define BN_MP_INIT_C
#define BN_MP_COUNT_BITS_C
#define BN_MP_DIV_2D_C
#define BN_MP_MUL_C
#define BN_S_MP_ADD_C
#define BN_MP_CMP_MAG_C
#define BN_S_MP_SUB_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_REDUCE_2K_SETUP_C)
#define BN_MP_INIT_C
#define BN_MP_COUNT_BITS_C
#define BN_MP_2EXPT_C
#define BN_MP_CLEAR_C
#define BN_S_MP_SUB_C
#endif
#if defined(BN_MP_REDUCE_2K_SETUP_L_C)
#define BN_MP_INIT_C
#define BN_MP_2EXPT_C
#define BN_MP_COUNT_BITS_C
#define BN_S_MP_SUB_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_REDUCE_IS_2K_C)
#define BN_MP_REDUCE_2K_C
#define BN_MP_COUNT_BITS_C
#endif
#if defined(BN_MP_REDUCE_IS_2K_L_C)
#endif
#if defined(BN_MP_REDUCE_SETUP_C)
#define BN_MP_2EXPT_C
#define BN_MP_DIV_C
#endif
#if defined(BN_MP_RSHD_C)
#define BN_MP_ZERO_C
#endif
#if defined(BN_MP_SET_C)
#define BN_MP_ZERO_C
#endif
#if defined(BN_MP_SET_INT_C)
#define BN_MP_ZERO_C
#define BN_MP_MUL_2D_C
#define BN_MP_CLAMP_C
#endif
#if defined(BN_MP_SET_LONG_C)
#endif
#if defined(BN_MP_SET_LONG_LONG_C)
#endif
#if defined(BN_MP_SHRINK_C)
#endif
#if defined(BN_MP_SIGNED_BIN_SIZE_C)
#define BN_MP_UNSIGNED_BIN_SIZE_C
#endif
#if defined(BN_MP_SQR_C)
#define BN_MP_TOOM_SQR_C
#define BN_MP_KARATSUBA_SQR_C
#define BN_FAST_S_MP_SQR_C
#define BN_S_MP_SQR_C
#endif
#if defined(BN_MP_SQRMOD_C)
#define BN_MP_INIT_C
#define BN_MP_SQR_C
#define BN_MP_CLEAR_C
#define BN_MP_MOD_C
#endif
#if defined(BN_MP_SQRT_C)
#define BN_MP_N_ROOT_C
#define BN_MP_ISZERO_C
#define BN_MP_ZERO_C
#define BN_MP_INIT_COPY_C
#define BN_MP_RSHD_C
#define BN_MP_DIV_C
#define BN_MP_ADD_C
#define BN_MP_DIV_2_C
#define BN_MP_CMP_MAG_C
#define BN_MP_EXCH_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_SQRTMOD_PRIME_C)
#define BN_MP_CMP_D_C
#define BN_MP_ZERO_C
#define BN_MP_JACOBI_C
#define BN_MP_INIT_MULTI_C
#define BN_MP_MOD_D_C
#define BN_MP_ADD_D_C
#define BN_MP_DIV_2_C
#define BN_MP_EXPTMOD_C
#define BN_MP_COPY_C
#define BN_MP_SUB_D_C
#define BN_MP_ISEVEN_C
#define BN_MP_SET_INT_C
#define BN_MP_SQRMOD_C
#define BN_MP_MULMOD_C
#define BN_MP_SET_C
#define BN_MP_CLEAR_MULTI_C
#endif
#if defined(BN_MP_SUB_C)
#define BN_S_MP_ADD_C
#define BN_MP_CMP_MAG_C
#define BN_S_MP_SUB_C
#endif
#if defined(BN_MP_SUB_D_C)
#define BN_MP_GROW_C
#define BN_MP_ADD_D_C
#define BN_MP_CLAMP_C
#endif
#if defined(BN_MP_SUBMOD_C)
#define BN_MP_INIT_C
#define BN_MP_SUB_C
#define BN_MP_CLEAR_C
#define BN_MP_MOD_C
#endif
#if defined(BN_MP_TO_SIGNED_BIN_C)
#define BN_MP_TO_UNSIGNED_BIN_C
#endif
#if defined(BN_MP_TO_SIGNED_BIN_N_C)
#define BN_MP_SIGNED_BIN_SIZE_C
#define BN_MP_TO_SIGNED_BIN_C
#endif
#if defined(BN_MP_TO_UNSIGNED_BIN_C)
#define BN_MP_INIT_COPY_C
#define BN_MP_ISZERO_C
#define BN_MP_DIV_2D_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_TO_UNSIGNED_BIN_N_C)
#define BN_MP_UNSIGNED_BIN_SIZE_C
#define BN_MP_TO_UNSIGNED_BIN_C
#endif
#if defined(BN_MP_TOOM_MUL_C)
#define BN_MP_INIT_MULTI_C
#define BN_MP_MOD_2D_C
#define BN_MP_COPY_C
#define BN_MP_RSHD_C
#define BN_MP_MUL_C
#define BN_MP_MUL_2_C
#define BN_MP_ADD_C
#define BN_MP_SUB_C
#define BN_MP_DIV_2_C
#define BN_MP_MUL_2D_C
#define BN_MP_MUL_D_C
#define BN_MP_DIV_3_C
#define BN_MP_LSHD_C
#define BN_MP_CLEAR_MULTI_C
#endif
#if defined(BN_MP_TOOM_SQR_C)
#define BN_MP_INIT_MULTI_C
#define BN_MP_MOD_2D_C
#define BN_MP_COPY_C
#define BN_MP_RSHD_C
#define BN_MP_SQR_C
#define BN_MP_MUL_2_C
#define BN_MP_ADD_C
#define BN_MP_SUB_C
#define BN_MP_DIV_2_C
#define BN_MP_MUL_2D_C
#define BN_MP_MUL_D_C
#define BN_MP_DIV_3_C
#define BN_MP_LSHD_C
#define BN_MP_CLEAR_MULTI_C
#endif
#if defined(BN_MP_TORADIX_C)
#define BN_MP_ISZERO_C
#define BN_MP_INIT_COPY_C
#define BN_MP_DIV_D_C
#define BN_MP_CLEAR_C
#define BN_MP_S_RMAP_C
#endif
#if defined(BN_MP_TORADIX_N_C)
#define BN_MP_ISZERO_C
#define BN_MP_INIT_COPY_C
#define BN_MP_DIV_D_C
#define BN_MP_CLEAR_C
#define BN_MP_S_RMAP_C
#endif
#if defined(BN_MP_UNSIGNED_BIN_SIZE_C)
#define BN_MP_COUNT_BITS_C
#endif
#if defined(BN_MP_XOR_C)
#define BN_MP_INIT_COPY_C
#define BN_MP_CLAMP_C
#define BN_MP_EXCH_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_ZERO_C)
#endif
#if defined(BN_PRIME_TAB_C)
#endif
#if defined(BN_REVERSE_C)
#endif
#if defined(BN_S_MP_ADD_C)
#define BN_MP_GROW_C
#define BN_MP_CLAMP_C
#endif
#if defined(BN_S_MP_EXPTMOD_C)
#define BN_MP_COUNT_BITS_C
#define BN_MP_INIT_C
#define BN_MP_CLEAR_C
#define BN_MP_REDUCE_SETUP_C
#define BN_MP_REDUCE_C
#define BN_MP_REDUCE_2K_SETUP_L_C
#define BN_MP_REDUCE_2K_L_C
#define BN_MP_MOD_C
#define BN_MP_COPY_C
#define BN_MP_SQR_C
#define BN_MP_MUL_C
#define BN_MP_SET_C
#define BN_MP_EXCH_C
#endif
#if defined(BN_S_MP_MUL_DIGS_C)
#define BN_FAST_S_MP_MUL_DIGS_C
#define BN_MP_INIT_SIZE_C
#define BN_MP_CLAMP_C
#define BN_MP_EXCH_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_S_MP_MUL_HIGH_DIGS_C)
#define BN_FAST_S_MP_MUL_HIGH_DIGS_C
#define BN_MP_INIT_SIZE_C
#define BN_MP_CLAMP_C
#define BN_MP_EXCH_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_S_MP_SQR_C)
#define BN_MP_INIT_SIZE_C
#define BN_MP_CLAMP_C
#define BN_MP_EXCH_C
#define BN_MP_CLEAR_C
#endif
#if defined(BN_S_MP_SUB_C)
#define BN_MP_GROW_C
#define BN_MP_CLAMP_C
#endif
#if defined(BNCORE_C)
#endif
#ifdef LTM3
#define LTM_LAST
#endif
#else
#define LTM_LAST
#endif
#else
#define LTM_LAST
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* detect 64-bit mode if possible */
#if defined(__x86_64__)
#if !(defined(MP_32BIT) || defined(MP_16BIT) || defined(MP_8BIT))
#define MP_64BIT
#endif
#endif
/* some default configurations.
*
* A "mp_digit" must be able to hold DIGIT_BIT + 1 bits
* A "mp_word" must be able to hold 2*DIGIT_BIT + 1 bits
*
* At the very least a mp_digit must be able to hold 7 bits
* [any size beyond that is ok provided it doesn't overflow the data type]
*/
#ifdef MP_8BIT
typedef uint8_t mp_digit;
typedef uint16_t mp_word;
#define MP_SIZEOF_MP_DIGIT 1
#ifdef DIGIT_BIT
#error You must not define DIGIT_BIT when using MP_8BIT
#endif
#elif defined(MP_16BIT)
typedef uint16_t mp_digit;
typedef uint32_t mp_word;
#define MP_SIZEOF_MP_DIGIT 2
#ifdef DIGIT_BIT
#error You must not define DIGIT_BIT when using MP_16BIT
#endif
#elif defined(MP_64BIT)
/* for GCC only on supported platforms */
#ifndef CRYPT
typedef unsigned long long ulong64;
typedef signed long long long64;
#endif
typedef uint64_t mp_digit;
#if defined(_WIN32)
typedef unsigned __int128 mp_word;
#elif defined(__GNUC__)
typedef unsigned long mp_word __attribute__ ((mode(TI)));
#else
/* it seems you have a problem
* but we assume you can somewhere define your own uint128_t */
typedef uint128_t mp_word;
#endif
#define DIGIT_BIT 60
#else
/* this is the default case, 28-bit digits */
/* this is to make porting into LibTomCrypt easier :-) */
#ifndef CRYPT
typedef unsigned long long ulong64;
typedef signed long long long64;
#endif
typedef uint32_t mp_digit;
typedef uint64_t mp_word;
#ifdef MP_31BIT
/* this is an extension that uses 31-bit digits */
#define DIGIT_BIT 31
#else
/* default case is 28-bit digits, defines MP_28BIT as a handy macro to test */
#define DIGIT_BIT 28
#define MP_28BIT
#endif
#endif
/* otherwise the bits per digit is calculated automatically from the size of a mp_digit */
#ifndef DIGIT_BIT
#define DIGIT_BIT (((CHAR_BIT * MP_SIZEOF_MP_DIGIT) - 1)) /* bits per digit */
typedef uint_least32_t mp_min_u32;
#else
typedef mp_digit mp_min_u32;
#endif
/* use our internal implementation of alleged alleged rc4 */
#define MP_GEN_RANDOM aarc4random_maybe
#define MP_DIGIT_BIT DIGIT_BIT
#define MP_MASK ((((mp_digit)1) << ((mp_digit)DIGIT_BIT)) - ((mp_digit)1))
#define MP_DIGIT_MAX MP_MASK
/* equalities */
#define MP_LT -1 /* less than */
#define MP_EQ 0 /* equal to */
#define MP_GT 1 /* greater than */
#define MP_ZPOS 0 /* positive integer */
#define MP_NEG 1 /* negative */
#define MP_OKAY 0 /* ok result */
#define MP_MEM -2 /* out of mem */
#define MP_VAL -3 /* invalid input */
#define MP_RANGE MP_VAL
#define MP_YES 1 /* yes response */
#define MP_NO 0 /* no response */
/* Primality generation flags */
#define LTM_PRIME_BBS 0x0001 /* BBS style prime */
#define LTM_PRIME_SAFE 0x0002 /* Safe prime (p-1)/2 == prime */
#define LTM_PRIME_2MSB_ON 0x0008 /* force 2nd MSB to 1 */
typedef int mp_err;
/* you'll have to tune these... */
extern int KARATSUBA_MUL_CUTOFF,
KARATSUBA_SQR_CUTOFF,
TOOM_MUL_CUTOFF,
TOOM_SQR_CUTOFF;
/* define this to use lower memory usage routines (exptmods mostly) */
/* #define MP_LOW_MEM */
/* default precision */
#ifndef MP_PREC
#ifndef MP_LOW_MEM
#define MP_PREC 32 /* default digits of precision */
#else
#define MP_PREC 8 /* default digits of precision */
#endif
#endif
/* size of comba arrays, should be at least 2 * 2**(BITS_PER_WORD - BITS_PER_DIGIT*2) */
#define MP_WARRAY (1 << (((sizeof(mp_word) * CHAR_BIT) - (2 * DIGIT_BIT)) + 1))
/* the infamous mp_int structure */
typedef struct {
int used, alloc, sign;
mp_digit *dp;
} mp_int;
/* callback for mp_prime_random, should fill dst with random bytes and return how many read [upto len] */
typedef int ltm_prime_callback (unsigned char *dst, int len, void *dat);
#define USED(m) ((m)->used)
#define DIGIT(m, k) ((m)->dp[(k)])
#define SIGN(m) ((m)->sign)
/* error code to char* string */
const char *mp_error_to_string(int code);
/* ---> init and deinit bignum functions <--- */
/* init a bignum */
int mp_init(mp_int *a);
/* free a bignum */
void mp_clear(mp_int *a);
/* init a null terminated series of arguments */
int mp_init_multi(mp_int *mp, ...);
/* clear a null terminated series of arguments */
void mp_clear_multi(mp_int *mp, ...);
/* exchange two ints */
void mp_exch(mp_int *a, mp_int *b);
/* shrink ram required for a bignum */
int mp_shrink(mp_int *a);
/* grow an int to a given size */
int mp_grow(mp_int *a, int size);
/* init to a given number of digits */
int mp_init_size(mp_int *a, int size);
/* ---> Basic Manipulations <--- */
#define mp_iszero(a) (((a)->used == 0) ? MP_YES : MP_NO)
#define mp_iseven(a) ((((a)->used > 0) && (((a)->dp[0] & 1u) == 0u)) ? MP_YES : MP_NO)
#define mp_isodd(a) ((((a)->used > 0) && (((a)->dp[0] & 1u) == 1u)) ? MP_YES : MP_NO)
#define mp_isneg(a) (((a)->sign != MP_ZPOS) ? MP_YES : MP_NO)
/* set to zero */
void mp_zero(mp_int *a);
/* set to a digit */
void mp_set(mp_int *a, mp_digit b);
/* set a 32-bit const */
int mp_set_int(mp_int *a, unsigned long b);
/* set a platform dependent unsigned long value */
int mp_set_long(mp_int *a, unsigned long b);
/* set a platform dependent unsigned long long value */
int mp_set_long_long(mp_int *a, unsigned long long b);
/* get a 32-bit value */
unsigned long mp_get_int(mp_int *a);
/* get a platform dependent unsigned long value */
unsigned long mp_get_long(mp_int *a);
/* get a platform dependent unsigned long long value */
unsigned long long mp_get_long_long(mp_int *a);
/* initialize and set a digit */
int mp_init_set(mp_int *a, mp_digit b);
/* initialize and set 32-bit value */
int mp_init_set_int(mp_int *a, unsigned long b);
/* copy, b = a */
int mp_copy(mp_int *a, mp_int *b);
/* inits and copies, a = b */
int mp_init_copy(mp_int *a, mp_int *b);
/* trim unused digits */
void mp_clamp(mp_int *a);
/* import binary data */
int mp_import(mp_int *rop, size_t count, int order, size_t size, int endian, size_t nails, const void *op);
/* export binary data */
int mp_export(void *rop, size_t *countp, int order, size_t size, int endian, size_t nails, mp_int *op);
/* ---> digit manipulation <--- */
/* right shift by "b" digits */
void mp_rshd(mp_int *a, int b);
/* left shift by "b" digits */
int mp_lshd(mp_int *a, int b);
/* c = a / 2**b, implemented as c = a >> b */
int mp_div_2d(mp_int *a, int b, mp_int *c, mp_int *d);
/* b = a/2 */
int mp_div_2(mp_int *a, mp_int *b);
/* c = a * 2**b, implemented as c = a << b */
int mp_mul_2d(mp_int *a, int b, mp_int *c);
/* b = a*2 */
int mp_mul_2(mp_int *a, mp_int *b);
/* c = a mod 2**b */
int mp_mod_2d(mp_int *a, int b, mp_int *c);
/* computes a = 2**b */
int mp_2expt(mp_int *a, int b);
/* Counts the number of lsbs which are zero before the first zero bit */
int mp_cnt_lsb(mp_int *a);
/* I Love Earth! */
/* makes a pseudo-random int of a given size */
int mp_rand(mp_int *a, int digits);
/* ---> binary operations <--- */
/* c = a XOR b */
int mp_xor(mp_int *a, mp_int *b, mp_int *c);
/* c = a OR b */
int mp_or(mp_int *a, mp_int *b, mp_int *c);
/* c = a AND b */
int mp_and(mp_int *a, mp_int *b, mp_int *c);
/* ---> Basic arithmetic <--- */
/* b = -a */
int mp_neg(mp_int *a, mp_int *b);
/* b = |a| */
int mp_abs(mp_int *a, mp_int *b);
/* compare a to b */
int mp_cmp(mp_int *a, mp_int *b);
/* compare |a| to |b| */
int mp_cmp_mag(mp_int *a, mp_int *b);
/* c = a + b */
int mp_add(mp_int *a, mp_int *b, mp_int *c);
/* c = a - b */
int mp_sub(mp_int *a, mp_int *b, mp_int *c);
/* c = a * b */
int mp_mul(mp_int *a, mp_int *b, mp_int *c);
/* b = a*a */
int mp_sqr(mp_int *a, mp_int *b);
/* a/b => cb + d == a */
int mp_div(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
/* c = a mod b, 0 <= c < b */
int mp_mod(mp_int *a, mp_int *b, mp_int *c);
/* ---> single digit functions <--- */
/* compare against a single digit */
int mp_cmp_d(mp_int *a, mp_digit b);
/* c = a + b */
int mp_add_d(mp_int *a, mp_digit b, mp_int *c);
/* c = a - b */
int mp_sub_d(mp_int *a, mp_digit b, mp_int *c);
/* c = a * b */
int mp_mul_d(mp_int *a, mp_digit b, mp_int *c);
/* a/b => cb + d == a */
int mp_div_d(mp_int *a, mp_digit b, mp_int *c, mp_digit *d);
/* a/3 => 3c + d == a */
int mp_div_3(mp_int *a, mp_int *c, mp_digit *d);
/* c = a**b */
int mp_expt_d(mp_int *a, mp_digit b, mp_int *c);
int mp_expt_d_ex(mp_int *a, mp_digit b, mp_int *c, int fast);
/* c = a mod b, 0 <= c < b */
int mp_mod_d(mp_int *a, mp_digit b, mp_digit *c);
/* ---> number theory <--- */
/* d = a + b (mod c) */
int mp_addmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
/* d = a - b (mod c) */
int mp_submod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
/* d = a * b (mod c) */
int mp_mulmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
/* c = a * a (mod b) */
int mp_sqrmod(mp_int *a, mp_int *b, mp_int *c);
/* c = 1/a (mod b) */
int mp_invmod(mp_int *a, mp_int *b, mp_int *c);
/* c = (a, b) */
int mp_gcd(mp_int *a, mp_int *b, mp_int *c);
/* produces value such that U1*a + U2*b = U3 */
int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3);
/* c = [a, b] or (a*b)/(a, b) */
int mp_lcm(mp_int *a, mp_int *b, mp_int *c);
/* finds one of the b'th root of a, such that |c|**b <= |a|
*
* returns error if a < 0 and b is even
*/
int mp_n_root(mp_int *a, mp_digit b, mp_int *c);
int mp_n_root_ex(mp_int *a, mp_digit b, mp_int *c, int fast);
/* special sqrt algo */
int mp_sqrt(mp_int *arg, mp_int *ret);
/* special sqrt (mod prime) */
int mp_sqrtmod_prime(mp_int *arg, mp_int *prime, mp_int *ret);
/* is number a square? */
int mp_is_square(mp_int *arg, int *ret);
/* computes the jacobi c = (a | n) (or Legendre if b is prime) */
int mp_jacobi(mp_int *a, mp_int *n, int *c);
/* used to setup the Barrett reduction for a given modulus b */
int mp_reduce_setup(mp_int *a, mp_int *b);
/* Barrett Reduction, computes a (mod b) with a precomputed value c
*
* Assumes that 0 < a <= b*b, note if 0 > a > -(b*b) then you can merely
* compute the reduction as -1 * mp_reduce(mp_abs(a)) [pseudo code].
*/
int mp_reduce(mp_int *a, mp_int *b, mp_int *c);
/* setups the montgomery reduction */
int mp_montgomery_setup(mp_int *a, mp_digit *mp);
/* computes a = B**n mod b without division or multiplication useful for
* normalizing numbers in a Montgomery system.
*/
int mp_montgomery_calc_normalization(mp_int *a, mp_int *b);
/* computes x/R == x (mod N) via Montgomery Reduction */
int mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp);
/* returns 1 if a is a valid DR modulus */
int mp_dr_is_modulus(mp_int *a);
/* sets the value of "d" required for mp_dr_reduce */
void mp_dr_setup(mp_int *a, mp_digit *d);
/* reduces a modulo b using the Diminished Radix method */
int mp_dr_reduce(mp_int *a, mp_int *b, mp_digit mp);
/* returns true if a can be reduced with mp_reduce_2k */
int mp_reduce_is_2k(mp_int *a);
/* determines k value for 2k reduction */
int mp_reduce_2k_setup(mp_int *a, mp_digit *d);
/* reduces a modulo b where b is of the form 2**p - k [0 <= a] */
int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d);
/* returns true if a can be reduced with mp_reduce_2k_l */
int mp_reduce_is_2k_l(mp_int *a);
/* determines k value for 2k reduction */
int mp_reduce_2k_setup_l(mp_int *a, mp_int *d);
/* reduces a modulo b where b is of the form 2**p - k [0 <= a] */
int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d);
/* d = a**b (mod c) */
int mp_exptmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
/* ---> Primes <--- */
/* number of primes */
#ifdef MP_8BIT
#define PRIME_SIZE 31
#else
#define PRIME_SIZE 256
#endif
/* table of first PRIME_SIZE primes */
extern const mp_digit ltm_prime_tab[PRIME_SIZE];
/* result=1 if a is divisible by one of the first PRIME_SIZE primes */
int mp_prime_is_divisible(mp_int *a, int *result);
/* performs one Fermat test of "a" using base "b".
* Sets result to 0 if composite or 1 if probable prime
*/
int mp_prime_fermat(mp_int *a, mp_int *b, int *result);
/* performs one Miller-Rabin test of "a" using base "b".
* Sets result to 0 if composite or 1 if probable prime
*/
int mp_prime_miller_rabin(mp_int *a, mp_int *b, int *result);
/* This gives [for a given bit size] the number of trials required
* such that Miller-Rabin gives a prob of failure lower than 2^-96
*/
int mp_prime_rabin_miller_trials(int size);
/* performs t rounds of Miller-Rabin on "a" using the first
* t prime bases. Also performs an initial sieve of trial
* division. Determines if "a" is prime with probability
* of error no more than (1/4)**t.
*
* Sets result to 1 if probably prime, 0 otherwise
*/
int mp_prime_is_prime(mp_int *a, int t, int *result);
/* finds the next prime after the number "a" using "t" trials
* of Miller-Rabin.
*
* bbs_style = 1 means the prime must be congruent to 3 mod 4
*/
int mp_prime_next_prime(mp_int *a, int t, int bbs_style);
/* makes a truly random prime of a given size (bytes),
* call with bbs = 1 if you want it to be congruent to 3 mod 4
*
* You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can
* have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself
* so it can be NULL
*
* The prime generated will be larger than 2^(8*size).
*/
#define mp_prime_random(a, t, size, bbs, cb, dat) mp_prime_random_ex(a, t, ((size) * 8) + 1, (bbs == 1) ? LTM_PRIME_BBS : 0, cb, dat)
/* makes a truly random prime of a given size (bits),
*
* Flags are as follows:
*
* LTM_PRIME_BBS - make prime congruent to 3 mod 4
* LTM_PRIME_SAFE - make sure (p-1)/2 is prime as well (implies LTM_PRIME_BBS)
* LTM_PRIME_2MSB_ON - make the 2nd highest bit one
*
* You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can
* have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself
* so it can be NULL
*
*/
int mp_prime_random_ex(mp_int *a, int t, int size, int flags, ltm_prime_callback cb, void *dat);
/* ---> radix conversion <--- */
int mp_count_bits(mp_int *a);
int mp_unsigned_bin_size(mp_int *a);
int mp_read_unsigned_bin(mp_int *a, const unsigned char *b, int c);
int mp_to_unsigned_bin(mp_int *a, unsigned char *b);
int mp_to_unsigned_bin_n(mp_int *a, unsigned char *b, unsigned long *outlen);
int mp_signed_bin_size(mp_int *a);
int mp_read_signed_bin(mp_int *a, const unsigned char *b, int c);
int mp_to_signed_bin(mp_int *a, unsigned char *b);
int mp_to_signed_bin_n(mp_int *a, unsigned char *b, unsigned long *outlen);
int mp_read_radix(mp_int *a, const char *str, int radix);
int mp_toradix(mp_int *a, char *str, int radix);
int mp_toradix_n(mp_int *a, char *str, int radix, int maxlen);
int mp_radix_size(mp_int *a, int radix, int *size);
#ifndef LTM_NO_FILE
int mp_fread(mp_int *a, int radix, FILE *stream);
int mp_fwrite(mp_int *a, int radix, FILE *stream);
#endif
#define mp_read_raw(mp, str, len) mp_read_signed_bin((mp), (str), (len))
#define mp_raw_size(mp) mp_signed_bin_size(mp)
#define mp_toraw(mp, str) mp_to_signed_bin((mp), (str))
#define mp_read_mag(mp, str, len) mp_read_unsigned_bin((mp), (str), (len))
#define mp_mag_size(mp) mp_unsigned_bin_size(mp)
#define mp_tomag(mp, str) mp_to_unsigned_bin((mp), (str))
#define mp_tobinary(M, S) mp_toradix((M), (S), 2)
#define mp_tooctal(M, S) mp_toradix((M), (S), 8)
#define mp_todecimal(M, S) mp_toradix((M), (S), 10)
#define mp_tohex(M, S) mp_toradix((M), (S), 16)
#ifdef __cplusplus
}
#endif
#endif
/*
* "Allegedly" Arc4 random number generator for OpenBSD.
* Copyright 1996 David Mazieres <dm@lcs.mit.edu>.
* Minor modifications by Cameron Kaiser for Crypto Ancienne.
*
* Modification and redistribution in source and binary forms is
* permitted provided that due credit is given to the author and the
* OpenBSD project by leaving this copyright notice intact.
*
* This code is derived from section 17.1 of Applied Cryptography,
* second edition, which describes a stream cipher allegedly
* compatible with RSA Labs "RC4" cipher (the actual description of
* which is a trade secret). The same algorithm is used as a stream
* cipher called "arcfour" in Tatu Ylonen's ssh package.
*
* RC4 is a registered trademark of RSA Laboratories.
*/
struct aarc4_stream {
uint8_t i;
uint8_t j;
uint8_t s[256];
};
static int rs_initialized = 0;
static struct aarc4_stream rs;
static int aarc4_count;
static int aarc4_use_dev_urandom = -1;
static void
aarc4_init(struct aarc4_stream *as)
{
int n;
for (n = 0; n < 256; n++)
as->s[n] = n;
as->i = 0;
as->j = 0;
}
static void
aarc4_addrandom(struct aarc4_stream *as, unsigned char *dat, int datlen)
{
int n;
uint8_t si;
as->i--;
for (n = 0; n < 256; n++) {
as->i = (as->i + 1);
si = as->s[as->i];
as->j = (as->j + si + dat[n % datlen]);
as->s[as->i] = as->s[as->j];
as->s[as->j] = si;
}
as->j = as->i;
}
static uint8_t
aarc4_getbyte(struct aarc4_stream *as)
{
uint8_t si, sj;
as->i = (as->i + 1);
si = as->s[as->i];
as->j = (as->j + si);
sj = as->s[as->j];
as->s[as->i] = sj;
as->s[as->j] = si;
return (as->s[(si + sj) & 0xff]);
}
static uint32_t
aarc4_getword(struct aarc4_stream *as)
{
uint32_t val;
val = aarc4_getbyte(as) << 24;
val |= aarc4_getbyte(as) << 16;
val |= aarc4_getbyte(as) << 8;
val |= aarc4_getbyte(as);
return val;
}
static void
aarc4_stir(struct aarc4_stream *as)
{
FILE *f;
struct {
struct timeval tv;
unsigned int rnd[(128 - sizeof(struct timeval)) /
sizeof(unsigned int)];
} rdat;
int n;
/*
* The systems we specialize in almost all lack OS-provided RNGs.
* Time of day is used as a weak source of entropy in that case;
* we could probably add a PRNGD client in here as well.
* Still, if /dev/urandom exists, smoke 'em if you got 'em.
*/
gettimeofday(&rdat.tv, NULL);
if (aarc4_use_dev_urandom != 0) {
f = fopen("/dev/urandom", "rb");
if (f) {
aarc4_use_dev_urandom = 1;
n = fread(&rdat.rnd, sizeof(rdat.rnd), 1, f);
fclose(f);
} else {
/* Don't waste time checking again. */
aarc4_use_dev_urandom = 0;
}
}
aarc4_addrandom(as, (void *) &rdat, sizeof(rdat));
/*
* Throw away the first N words of output, as suggested in the
* paper "Weaknesses in the Key Scheduling Algorithm of RC4"
* by Fluher, Mantin, and Shamir. (N = 256 in our case.)
*/
for (n = 0; n < 256 * 4; n++)
aarc4_getbyte(as);
aarc4_count = 1600000;
}
void
aarc4random_stir()
{
if (!rs_initialized) {
aarc4_init(&rs);
rs_initialized = 1;
}
aarc4_stir(&rs);
}
void
aarc4random_addrandom(unsigned char *dat, int datlen)
{
if (!rs_initialized)
aarc4random_stir();
aarc4_addrandom(&rs, dat, datlen);
}
uint32_t
aarc4random_maybe()
{
/* I thought about having this read /dev/random, but there are
just too many questions about it depending on system version. */
aarc4_count -= 4;
if (!rs_initialized || aarc4_count <= 0)
aarc4random_stir();
return aarc4_getword(&rs);
}
size_t
aarc4random_batch_maybe(unsigned char *out, unsigned long outlen)
{
/* A batch version of the above. */
size_t i;
aarc4_count -= outlen;
if (!rs_initialized || aarc4_count <= outlen)
aarc4random_stir();
for (i=0; i<outlen; i++) {
out[i] = aarc4_getbyte(&rs);
}
return outlen;
}
/* $Source$ */
/* $Revision$ */
/* $Date$ */
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
* LibTomMath is a library that provides multiple-precision
* integer arithmetic as well as number theoretic functionality.
*
* The library was designed directly after the MPI library by
* Michael Fromberger but has been written from scratch with
* additional optimizations in place.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tstdenis82@gmail.com, http://math.libtomcrypt.com
*/
#ifndef TOMMATH_PRIV_H_
#define TOMMATH_PRIV_H_
#include <ctype.h>
#define TOM_MIN(x, y) (((x) < (y)) ? (x) : (y))
#define TOM_MAX(x, y) (((x) > (y)) ? (x) : (y))
#ifdef __cplusplus
extern "C" {
/* C++ compilers don't like assigning void * to mp_digit * */
#define OPT_CAST(x) (x *)
#else
/* C on the other hand doesn't care */
#define OPT_CAST(x)
#endif
/* define heap macros */
#ifndef XMALLOC
/* default to libc stuff */
#define XMALLOC malloc
#define XFREE free
#ifndef XREALLOC
#define XREALLOC realloc
#endif
#define XCALLOC calloc
#else
/* prototypes for our heap functions */
extern void *XMALLOC(size_t n);
extern void *XREALLOC(void *p, size_t n);
extern void *XCALLOC(size_t n, size_t s);
extern void XFREE(void *p);
#endif
/* lowlevel functions, do not call! */
int s_mp_add(mp_int *a, mp_int *b, mp_int *c);
int s_mp_sub(mp_int *a, mp_int *b, mp_int *c);
#define s_mp_mul(a, b, c) s_mp_mul_digs(a, b, c, (a)->used + (b)->used + 1)
int fast_s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs);
int s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs);
int fast_s_mp_mul_high_digs(mp_int *a, mp_int *b, mp_int *c, int digs);
int s_mp_mul_high_digs(mp_int *a, mp_int *b, mp_int *c, int digs);
int fast_s_mp_sqr(mp_int *a, mp_int *b);
int s_mp_sqr(mp_int *a, mp_int *b);
int mp_karatsuba_mul(mp_int *a, mp_int *b, mp_int *c);
int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c);
int mp_karatsuba_sqr(mp_int *a, mp_int *b);
int mp_toom_sqr(mp_int *a, mp_int *b);
int fast_mp_invmod(mp_int *a, mp_int *b, mp_int *c);
int mp_invmod_slow(mp_int *a, mp_int *b, mp_int *c);
int fast_mp_montgomery_reduce(mp_int *x, mp_int *n, mp_digit rho);
int mp_exptmod_fast(mp_int *G, mp_int *X, mp_int *P, mp_int *Y, int redmode);
int s_mp_exptmod(mp_int *G, mp_int *X, mp_int *P, mp_int *Y, int redmode);
void bn_reverse(unsigned char *s, int len);
extern const char *mp_s_rmap;
/* Fancy macro to set an MPI from another type.
* There are several things assumed:
* x is the counter and unsigned
* a is the pointer to the MPI
* b is the original value that should be set in the MPI.
*/
#define MP_SET_XLONG(func_name, type) \
int func_name(mp_int * a, type b) \
{ \
unsigned int x; \
int res; \
\
mp_zero(a); \
\
/* set four bits at a time */ \
for (x = 0; x < (sizeof(type) * 2u); x++) { \
/* shift the number up four bits */ \
if ((res = mp_mul_2d(a, 4, a)) != MP_OKAY) { \
return res; \
} \
\
/* OR in the top four bits of the source */ \
a->dp[0] |= (b >> ((sizeof(type) * 8u) - 4u)) & 15u; \
\
/* shift the source up to the next four bits */ \
b <<= 4; \
\
/* ensure that digits are not clamped off */ \
a->used += 1; \
} \
mp_clamp(a); \
return MP_OKAY; \
}
#ifdef __cplusplus
}
#endif
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
#define BN_FAST_MP_INVMOD_C
#ifdef BN_FAST_MP_INVMOD_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
* LibTomMath is a library that provides multiple-precision
* integer arithmetic as well as number theoretic functionality.
*
* The library was designed directly after the MPI library by
* Michael Fromberger but has been written from scratch with
* additional optimizations in place.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tstdenis82@gmail.com, http://libtom.org
*/
/* computes the modular inverse via binary extended euclidean algorithm,
* that is c = 1/a mod b
*
* Based on slow invmod except this is optimized for the case where b is
* odd as per HAC Note 14.64 on pp. 610
*/
int fast_mp_invmod(mp_int *a, mp_int *b, mp_int *c) {
mp_int x, y, u, v, B, D;
int res, neg;
/* 2. [modified] b must be odd */
if (mp_iseven(b) == MP_YES) {
return MP_VAL;
}
/* init all our temps */
if ((res = mp_init_multi(&x, &y, &u, &v, &B, &D, NULL)) != MP_OKAY) {
return res;
}
/* x == modulus, y == value to invert */
if ((res = mp_copy(b, &x)) != MP_OKAY) {
goto LBL_ERR;
}
/* we need y = |a| */
if ((res = mp_mod(a, b, &y)) != MP_OKAY) {
goto LBL_ERR;
}
/* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
if ((res = mp_copy(&x, &u)) != MP_OKAY) {
goto LBL_ERR;
}
if ((res = mp_copy(&y, &v)) != MP_OKAY) {
goto LBL_ERR;
}
mp_set(&D, 1);
top:
/* 4. while u is even do */
while (mp_iseven(&u) == MP_YES) {
/* 4.1 u = u/2 */
if ((res = mp_div_2(&u, &u)) != MP_OKAY) {
goto LBL_ERR;
}
/* 4.2 if B is odd then */
if (mp_isodd(&B) == MP_YES) {
if ((res = mp_sub(&B, &x, &B)) != MP_OKAY) {
goto LBL_ERR;
}
}
/* B = B/2 */
if ((res = mp_div_2(&B, &B)) != MP_OKAY) {
goto LBL_ERR;
}
}
/* 5. while v is even do */
while (mp_iseven(&v) == MP_YES) {
/* 5.1 v = v/2 */
if ((res = mp_div_2(&v, &v)) != MP_OKAY) {
goto LBL_ERR;
}
/* 5.2 if D is odd then */
if (mp_isodd(&D) == MP_YES) {
/* D = (D-x)/2 */
if ((res = mp_sub(&D, &x, &D)) != MP_OKAY) {
goto LBL_ERR;
}
}
/* D = D/2 */
if ((res = mp_div_2(&D, &D)) != MP_OKAY) {
goto LBL_ERR;
}
}
/* 6. if u >= v then */
if (mp_cmp(&u, &v) != MP_LT) {
/* u = u - v, B = B - D */
if ((res = mp_sub(&u, &v, &u)) != MP_OKAY) {
goto LBL_ERR;
}
if ((res = mp_sub(&B, &D, &B)) != MP_OKAY) {
goto LBL_ERR;
}
} else {
/* v - v - u, D = D - B */
if ((res = mp_sub(&v, &u, &v)) != MP_OKAY) {
goto LBL_ERR;
}
if ((res = mp_sub(&D, &B, &D)) != MP_OKAY) {
goto LBL_ERR;
}
}
/* if not zero goto step 4 */
if (mp_iszero(&u) == MP_NO) {
goto top;
}
/* now a = C, b = D, gcd == g*v */
/* if v != 1 then there is no inverse */
if (mp_cmp_d(&v, 1) != MP_EQ) {
res = MP_VAL;
goto LBL_ERR;
}
/* b is now the inverse */
neg = a->sign;
while (D.sign == MP_NEG) {
if ((res = mp_add(&D, b, &D)) != MP_OKAY) {
goto LBL_ERR;
}
}
mp_exch(&D, c);
c->sign = neg;
res = MP_OKAY;
LBL_ERR: mp_clear_multi(&x, &y, &u, &v, &B, &D, NULL);
return res;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
* LibTomMath is a library that provides multiple-precision
* integer arithmetic as well as number theoretic functionality.
*
* The library was designed directly after the MPI library by
* Michael Fromberger but has been written from scratch with
* additional optimizations in place.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tstdenis82@gmail.com, http://libtom.org
*/
/* computes xR**-1 == x (mod N) via Montgomery Reduction
*
* This is an optimized implementation of montgomery_reduce
* which uses the comba method to quickly calculate the columns of the
* reduction.
*
* Based on Algorithm 14.32 on pp.601 of HAC.
*/
int fast_mp_montgomery_reduce(mp_int *x, mp_int *n, mp_digit rho) {
int ix, res, olduse;
mp_word W[MP_WARRAY];
/* get old used count */
olduse = x->used;
/* grow a as required */
if (x->alloc < (n->used + 1)) {
if ((res = mp_grow(x, n->used + 1)) != MP_OKAY) {
return res;
}
}
/* first we have to get the digits of the input into
* an array of double precision words W[...]
*/
{
mp_word *_W;
mp_digit *tmpx;
/* alias for the W[] array */
_W = W;
/* alias for the digits of x*/
tmpx = x->dp;
/* copy the digits of a into W[0..a->used-1] */
for (ix = 0; ix < x->used; ix++) {
*_W++ = *tmpx++;
}
/* zero the high words of W[a->used..m->used*2] */
for ( ; ix < ((n->used * 2) + 1); ix++) {
*_W++ = 0;
}
}
/* now we proceed to zero successive digits
* from the least significant upwards
*/
for (ix = 0; ix < n->used; ix++) {
/* mu = ai * m' mod b
*
* We avoid a double precision multiplication (which isn't required)
* by casting the value down to a mp_digit. Note this requires
* that W[ix-1] have the carry cleared (see after the inner loop)
*/
mp_digit mu;
mu = (mp_digit)(((W[ix] & MP_MASK) * rho) & MP_MASK);
/* a = a + mu * m * b**i
*
* This is computed in place and on the fly. The multiplication
* by b**i is handled by offseting which columns the results
* are added to.
*
* Note the comba method normally doesn't handle carries in the
* inner loop In this case we fix the carry from the previous
* column since the Montgomery reduction requires digits of the
* result (so far) [see above] to work. This is
* handled by fixing up one carry after the inner loop. The
* carry fixups are done in order so after these loops the
* first m->used words of W[] have the carries fixed
*/
{
int iy;
mp_digit *tmpn;
mp_word *_W;
/* alias for the digits of the modulus */
tmpn = n->dp;
/* Alias for the columns set by an offset of ix */
_W = W + ix;
/* inner loop */
for (iy = 0; iy < n->used; iy++) {
*_W++ += ((mp_word)mu) * ((mp_word) * tmpn++);
}
}
/* now fix carry for next digit, W[ix+1] */
W[ix + 1] += W[ix] >> ((mp_word)DIGIT_BIT);
}
/* now we have to propagate the carries and
* shift the words downward [all those least
* significant digits we zeroed].
*/
{
mp_digit *tmpx;
mp_word *_W, *_W1;
/* nox fix rest of carries */
/* alias for current word */
_W1 = W + ix;
/* alias for next word, where the carry goes */
_W = W + ++ix;
for ( ; ix <= ((n->used * 2) + 1); ix++) {
*_W++ += *_W1++ >> ((mp_word)DIGIT_BIT);
}
/* copy out, A = A/b**n
*
* The result is A/b**n but instead of converting from an
* array of mp_word to mp_digit than calling mp_rshd
* we just copy them in the right order
*/
/* alias for destination word */
tmpx = x->dp;
/* alias for shifted double precision result */
_W = W + n->used;
for (ix = 0; ix < (n->used + 1); ix++) {
*tmpx++ = (mp_digit)(*_W++ & ((mp_word)MP_MASK));
}
/* zero oldused digits, if the input a was larger than
* m->used+1 we'll have to clear the digits
*/
for ( ; ix < olduse; ix++) {
*tmpx++ = 0;
}
}
/* set the max used and clamp */
x->used = n->used + 1;
mp_clamp(x);
/* if A >= m then A = A - m */
if (mp_cmp_mag(x, n) != MP_LT) {
return s_mp_sub(x, n, x);
}
return MP_OKAY;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
#ifdef BN_FAST_S_MP_MUL_DIGS_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
* LibTomMath is a library that provides multiple-precision
* integer arithmetic as well as number theoretic functionality.
*
* The library was designed directly after the MPI library by
* Michael Fromberger but has been written from scratch with
* additional optimizations in place.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tstdenis82@gmail.com, http://libtom.org
*/
/* Fast (comba) multiplier
*
* This is the fast column-array [comba] multiplier. It is
* designed to compute the columns of the product first
* then handle the carries afterwards. This has the effect
* of making the nested loops that compute the columns very
* simple and schedulable on super-scalar processors.
*
* This has been modified to produce a variable number of
* digits of output so if say only a half-product is required
* you don't have to compute the upper half (a feature
* required for fast Barrett reduction).
*
* Based on Algorithm 14.12 on pp.595 of HAC.
*
*/
int fast_s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs) {
int olduse, res, pa, ix, iz;
mp_digit W[MP_WARRAY];
mp_word _W;
/* grow the destination as required */
if (c->alloc < digs) {
if ((res = mp_grow(c, digs)) != MP_OKAY) {
return res;
}
}
/* number of output digits to produce */
pa = TOM_MIN(digs, a->used + b->used);
/* clear the carry */
_W = 0;
for (ix = 0; ix < pa; ix++) {
int tx, ty;
int iy;
mp_digit *tmpx, *tmpy;
/* get offsets into the two bignums */
ty = TOM_MIN(b->used - 1, ix);
tx = ix - ty;
/* setup temp aliases */
tmpx = a->dp + tx;
tmpy = b->dp + ty;
/* this is the number of times the loop will iterrate, essentially
while (tx++ < a->used && ty-- >= 0) { ... }
*/
iy = TOM_MIN(a->used - tx, ty + 1);
/* execute loop */
for (iz = 0; iz < iy; ++iz) {
_W += ((mp_word) * tmpx++) * ((mp_word) * tmpy--);
}
/* store term */
W[ix] = ((mp_digit)_W) & MP_MASK;
/* make next carry */
_W = _W >> ((mp_word)DIGIT_BIT);
}
/* setup dest */
olduse = c->used;
c->used = pa;
{
mp_digit *tmpc;
tmpc = c->dp;
for (ix = 0; ix < (pa + 1); ix++) {
/* now extract the previous digit [below the carry] */
*tmpc++ = W[ix];
}
/* clear unused digits [that existed in the old copy of c] */
for ( ; ix < olduse; ix++) {
*tmpc++ = 0;
}
}
mp_clamp(c);
return MP_OKAY;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
#ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
* LibTomMath is a library that provides multiple-precision
* integer arithmetic as well as number theoretic functionality.
*
* The library was designed directly after the MPI library by
* Michael Fromberger but has been written from scratch with
* additional optimizations in place.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tstdenis82@gmail.com, http://libtom.org
*/
/* this is a modified version of fast_s_mul_digs that only produces
* output digits *above* digs. See the comments for fast_s_mul_digs
* to see how it works.
*
* This is used in the Barrett reduction since for one of the multiplications
* only the higher digits were needed. This essentially halves the work.
*
* Based on Algorithm 14.12 on pp.595 of HAC.
*/
int fast_s_mp_mul_high_digs(mp_int *a, mp_int *b, mp_int *c, int digs) {
int olduse, res, pa, ix, iz;
mp_digit W[MP_WARRAY];
mp_word _W;
/* grow the destination as required */
pa = a->used + b->used;
if (c->alloc < pa) {
if ((res = mp_grow(c, pa)) != MP_OKAY) {
return res;
}
}
/* number of output digits to produce */
pa = a->used + b->used;
_W = 0;
for (ix = digs; ix < pa; ix++) {
int tx, ty, iy;
mp_digit *tmpx, *tmpy;
/* get offsets into the two bignums */
ty = TOM_MIN(b->used - 1, ix);
tx = ix - ty;
/* setup temp aliases */
tmpx = a->dp + tx;
tmpy = b->dp + ty;
/* this is the number of times the loop will iterrate, essentially its
while (tx++ < a->used && ty-- >= 0) { ... }
*/
iy = TOM_MIN(a->used - tx, ty + 1);
/* execute loop */
for (iz = 0; iz < iy; iz++) {
_W += ((mp_word) * tmpx++) * ((mp_word) * tmpy--);
}
/* store term */
W[ix] = ((mp_digit)_W) & MP_MASK;
/* make next carry */
_W = _W >> ((mp_word)DIGIT_BIT);
}
/* setup dest */
olduse = c->used;
c->used = pa;
{
mp_digit *tmpc;
tmpc = c->dp + digs;
for (ix = digs; ix < pa; ix++) {
/* now extract the previous digit [below the carry] */
*tmpc++ = W[ix];
}
/* clear unused digits [that existed in the old copy of c] */
for ( ; ix < olduse; ix++) {
*tmpc++ = 0;
}
}
mp_clamp(c);
return MP_OKAY;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
#ifdef BN_FAST_S_MP_SQR_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
* LibTomMath is a library that provides multiple-precision
* integer arithmetic as well as number theoretic functionality.
*
* The library was designed directly after the MPI library by
* Michael Fromberger but has been written from scratch with
* additional optimizations in place.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tstdenis82@gmail.com, http://libtom.org
*/
/* the jist of squaring...
* you do like mult except the offset of the tmpx [one that
* starts closer to zero] can't equal the offset of tmpy.
* So basically you set up iy like before then you min it with
* (ty-tx) so that it never happens. You double all those
* you add in the inner loop
After that loop you do the squares and add them in.
*/
int fast_s_mp_sqr(mp_int *a, mp_int *b) {
int olduse, res, pa, ix, iz;
mp_digit W[MP_WARRAY], *tmpx;
mp_word W1;
/* grow the destination as required */
pa = a->used + a->used;
if (b->alloc < pa) {
if ((res = mp_grow(b, pa)) != MP_OKAY) {
return res;
}
}
/* number of output digits to produce */
W1 = 0;
for (ix = 0; ix < pa; ix++) {
int tx, ty, iy;
mp_word _W;
mp_digit *tmpy;
/* clear counter */
_W = 0;
/* get offsets into the two bignums */
ty = TOM_MIN(a->used - 1, ix);
tx = ix - ty;
/* setup temp aliases */
tmpx = a->dp + tx;
tmpy = a->dp + ty;
/* this is the number of times the loop will iterrate, essentially
while (tx++ < a->used && ty-- >= 0) { ... }
*/
iy = TOM_MIN(a->used - tx, ty + 1);
/* now for squaring tx can never equal ty
* we halve the distance since they approach at a rate of 2x
* and we have to round because odd cases need to be executed
*/
iy = TOM_MIN(iy, ((ty - tx) + 1) >> 1);
/* execute loop */
for (iz = 0; iz < iy; iz++) {
_W += ((mp_word) * tmpx++) * ((mp_word) * tmpy--);
}
/* double the inner product and add carry */
_W = _W + _W + W1;
/* even columns have the square term in them */
if ((ix & 1) == 0) {
_W += ((mp_word)a->dp[ix >> 1]) * ((mp_word)a->dp[ix >> 1]);
}
/* store it */
W[ix] = (mp_digit)(_W & MP_MASK);
/* make next carry */
W1 = _W >> ((mp_word)DIGIT_BIT);
}
/* setup dest */
olduse = b->used;
b->used = a->used + a->used;
{
mp_digit *tmpb;
tmpb = b->dp;
for (ix = 0; ix < pa; ix++) {
*tmpb++ = W[ix] & MP_MASK;
}
/* clear unused digits [that existed in the old copy of c] */
for ( ; ix < olduse; ix++) {
*tmpb++ = 0;
}
}
mp_clamp(b);
return MP_OKAY;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
#ifdef BN_MP_2EXPT_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
* LibTomMath is a library that provides multiple-precision
* integer arithmetic as well as number theoretic functionality.
*
* The library was designed directly after the MPI library by
* Michael Fromberger but has been written from scratch with
* additional optimizations in place.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tstdenis82@gmail.com, http://libtom.org
*/
/* computes a = 2**b
*
* Simple algorithm which zeroes the int, grows it then just sets one bit
* as required.
*/
int
mp_2expt(mp_int *a, int b) {
int res;
/* zero a as per default */
mp_zero(a);
/* grow a to accomodate the single bit */
if ((res = mp_grow(a, (b / DIGIT_BIT) + 1)) != MP_OKAY) {
return res;
}
/* set the used count of where the bit will go */
a->used = (b / DIGIT_BIT) + 1;
/* put the single bit in its place */
a->dp[b / DIGIT_BIT] = ((mp_digit)1) << (b % DIGIT_BIT);
return MP_OKAY;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
#ifdef BN_MP_ABS_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
* LibTomMath is a library that provides multiple-precision
* integer arithmetic as well as number theoretic functionality.
*
* The library was designed directly after the MPI library by
* Michael Fromberger but has been written from scratch with
* additional optimizations in place.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tstdenis82@gmail.com, http://libtom.org
*/
/* b = |a|
*
* Simple function copies the input and fixes the sign to positive
*/
int
mp_abs(mp_int *a, mp_int *b) {
int res;
/* copy a to b */
if (a != b) {
if ((res = mp_copy(a, b)) != MP_OKAY) {
return res;
}
}
/* force the sign of b to positive */
b->sign = MP_ZPOS;
return MP_OKAY;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
#ifdef BN_MP_ADD_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
* LibTomMath is a library that provides multiple-precision
* integer arithmetic as well as number theoretic functionality.
*
* The library was designed directly after the MPI library by
* Michael Fromberger but has been written from scratch with
* additional optimizations in place.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tstdenis82@gmail.com, http://libtom.org
*/
/* high level addition (handles signs) */
int mp_add(mp_int *a, mp_int *b, mp_int *c) {
int sa, sb, res;
/* get sign of both inputs */
sa = a->sign;
sb = b->sign;
/* handle two cases, not four */
if (sa == sb) {
/* both positive or both negative */
/* add their magnitudes, copy the sign */
c->sign = sa;
res = s_mp_add(a, b, c);
} else {
/* one positive, the other negative */
/* subtract the one with the greater magnitude from */
/* the one of the lesser magnitude. The result gets */
/* the sign of the one with the greater magnitude. */
if (mp_cmp_mag(a, b) == MP_LT) {
c->sign = sb;
res = s_mp_sub(b, a, c);
} else {
c->sign = sa;
res = s_mp_sub(a, b, c);
}
}
return res;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
#ifdef BN_MP_ADD_D_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
* LibTomMath is a library that provides multiple-precision
* integer arithmetic as well as number theoretic functionality.
*
* The library was designed directly after the MPI library by
* Michael Fromberger but has been written from scratch with
* additional optimizations in place.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tstdenis82@gmail.com, http://libtom.org
*/
/* single digit addition */
int
mp_add_d(mp_int *a, mp_digit b, mp_int *c) {
int res, ix, oldused;
mp_digit *tmpa, *tmpc, mu;
/* grow c as required */
if (c->alloc < (a->used + 1)) {
if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) {
return res;
}
}
/* if a is negative and |a| >= b, call c = |a| - b */
if ((a->sign == MP_NEG) && ((a->used > 1) || (a->dp[0] >= b))) {
/* temporarily fix sign of a */
a->sign = MP_ZPOS;
/* c = |a| - b */
res = mp_sub_d(a, b, c);
/* fix sign */
a->sign = c->sign = MP_NEG;
/* clamp */
mp_clamp(c);
return res;
}
/* old number of used digits in c */
oldused = c->used;
/* sign always positive */
c->sign = MP_ZPOS;
/* source alias */
tmpa = a->dp;
/* destination alias */
tmpc = c->dp;
/* if a is positive */
if (a->sign == MP_ZPOS) {
/* add digit, after this we're propagating
* the carry.
*/
*tmpc = *tmpa++ + b;
mu = *tmpc >> DIGIT_BIT;
*tmpc++ &= MP_MASK;
/* now handle rest of the digits */
for (ix = 1; ix < a->used; ix++) {
*tmpc = *tmpa++ + mu;
mu = *tmpc >> DIGIT_BIT;
*tmpc++ &= MP_MASK;
}
/* set final carry */
ix++;
*tmpc++ = mu;
/* setup size */
c->used = a->used + 1;
} else {
/* a was negative and |a| < b */
c->used = 1;
/* the result is a single digit */
if (a->used == 1) {
*tmpc++ = b - a->dp[0];
} else {
*tmpc++ = b;
}
/* setup count so the clearing of oldused
* can fall through correctly
*/
ix = 1;
}
/* now zero to oldused */
while (ix++ < oldused) {
*tmpc++ = 0;
}
mp_clamp(c);
return MP_OKAY;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
#ifdef BN_MP_ADDMOD_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
* LibTomMath is a library that provides multiple-precision
* integer arithmetic as well as number theoretic functionality.
*
* The library was designed directly after the MPI library by
* Michael Fromberger but has been written from scratch with
* additional optimizations in place.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tstdenis82@gmail.com, http://libtom.org
*/
/* d = a + b (mod c) */
int
mp_addmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d) {
int res;
mp_int t;
if ((res = mp_init(&t)) != MP_OKAY) {
return res;
}
if ((res = mp_add(a, b, &t)) != MP_OKAY) {
mp_clear(&t);
return res;
}
res = mp_mod(&t, c, d);
mp_clear(&t);
return res;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
#ifdef BN_MP_AND_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
* LibTomMath is a library that provides multiple-precision
* integer arithmetic as well as number theoretic functionality.
*
* The library was designed directly after the MPI library by
* Michael Fromberger but has been written from scratch with
* additional optimizations in place.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tstdenis82@gmail.com, http://libtom.org
*/
/* AND two ints together */
int
mp_and(mp_int *a, mp_int *b, mp_int *c) {
int res, ix, px;
mp_int t, *x;
if (a->used > b->used) {
if ((res = mp_init_copy(&t, a)) != MP_OKAY) {
return res;
}
px = b->used;
x = b;
} else {
if ((res = mp_init_copy(&t, b)) != MP_OKAY) {
return res;
}
px = a->used;
x = a;
}
for (ix = 0; ix < px; ix++) {
t.dp[ix] &= x->dp[ix];
}
/* zero digits above the last from the smallest mp_int */
for ( ; ix < t.used; ix++) {
t.dp[ix] = 0;
}
mp_clamp(&t);
mp_exch(c, &t);
mp_clear(&t);
return MP_OKAY;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
#ifdef BN_MP_CLAMP_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
* LibTomMath is a library that provides multiple-precision
* integer arithmetic as well as number theoretic functionality.
*
* The library was designed directly after the MPI library by
* Michael Fromberger but has been written from scratch with
* additional optimizations in place.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tstdenis82@gmail.com, http://libtom.org
*/
/* trim unused digits
*
* This is used to ensure that leading zero digits are
* trimed and the leading "used" digit will be non-zero
* Typically very fast. Also fixes the sign if there
* are no more leading digits
*/
void
mp_clamp(mp_int *a) {
/* decrease used while the most significant digit is
* zero.
*/
while ((a->used > 0) && (a->dp[a->used - 1] == 0)) {
--(a->used);
}
/* reset the sign flag if used == 0 */
if (a->used == 0) {
a->sign = MP_ZPOS;
}
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
#ifdef BN_MP_CLEAR_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
* LibTomMath is a library that provides multiple-precision
* integer arithmetic as well as number theoretic functionality.
*
* The library was designed directly after the MPI library by
* Michael Fromberger but has been written from scratch with
* additional optimizations in place.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tstdenis82@gmail.com, http://libtom.org
*/
/* clear one (frees) */
void
mp_clear(mp_int *a) {
int i;
/* only do anything if a hasn't been freed previously */
if (a->dp != NULL) {
/* first zero the digits */
for (i = 0; i < a->used; i++) {
a->dp[i] = 0;
}
/* free ram */
XFREE(a->dp);
/* reset members to make debugging easier */
a->dp = NULL;
a->alloc = a->used = 0;
a->sign = MP_ZPOS;
}
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
#ifdef BN_MP_CLEAR_MULTI_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
* LibTomMath is a library that provides multiple-precision
* integer arithmetic as well as number theoretic functionality.
*
* The library was designed directly after the MPI library by
* Michael Fromberger but has been written from scratch with
* additional optimizations in place.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tstdenis82@gmail.com, http://libtom.org
*/
void mp_clear_multi(mp_int *mp, ...) {
mp_int *next_mp = mp;
va_list args;
va_start(args, mp);
while (next_mp != NULL) {
mp_clear(next_mp);
next_mp = va_arg(args, mp_int *);
}
va_end(args);
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
#ifdef BN_MP_CMP_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
* LibTomMath is a library that provides multiple-precision
* integer arithmetic as well as number theoretic functionality.
*
* The library was designed directly after the MPI library by
* Michael Fromberger but has been written from scratch with
* additional optimizations in place.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tstdenis82@gmail.com, http://libtom.org
*/
/* compare two ints (signed)*/
int
mp_cmp(mp_int *a, mp_int *b) {
/* compare based on sign */
if (a->sign != b->sign) {
if (a->sign == MP_NEG) {
return MP_LT;
} else {
return MP_GT;
}
}
/* compare digits */
if (a->sign == MP_NEG) {
/* if negative compare opposite direction */
return mp_cmp_mag(b, a);
} else {
return mp_cmp_mag(a, b);
}
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
#ifdef BN_MP_CMP_D_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
* LibTomMath is a library that provides multiple-precision
* integer arithmetic as well as number theoretic functionality.
*
* The library was designed directly after the MPI library by
* Michael Fromberger but has been written from scratch with
* additional optimizations in place.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tstdenis82@gmail.com, http://libtom.org
*/
/* compare a digit */
int mp_cmp_d(mp_int *a, mp_digit b) {
/* compare based on sign */
if (a->sign == MP_NEG) {
return MP_LT;
}
/* compare based on magnitude */
if (a->used > 1) {
return MP_GT;
}
/* compare the only digit of a to b */
if (a->dp[0] > b) {
return MP_GT;
} else if (a->dp[0] < b) {
return MP_LT;
} else {
return MP_EQ;
}
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
#ifdef BN_MP_CMP_MAG_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
* LibTomMath is a library that provides multiple-precision
* integer arithmetic as well as number theoretic functionality.
*
* The library was designed directly after the MPI library by
* Michael Fromberger but has been written from scratch with
* additional optimizations in place.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tstdenis82@gmail.com, http://libtom.org
*/
/* compare maginitude of two ints (unsigned) */
int mp_cmp_mag(mp_int *a, mp_int *b) {
int n;
mp_digit *tmpa, *tmpb;
/* compare based on # of non-zero digits */
if (a->used > b->used) {
return MP_GT;
}
if (a->used < b->used) {
return MP_LT;
}
/* alias for a */
tmpa = a->dp + (a->used - 1);
/* alias for b */
tmpb = b->dp + (a->used - 1);
/* compare based on digits */
for (n = 0; n < a->used; ++n, --tmpa, --tmpb) {
if (*tmpa > *tmpb) {
return MP_GT;
}
if (*tmpa < *tmpb) {
return MP_LT;
}
}
return MP_EQ;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
#ifdef BN_MP_CNT_LSB_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
* LibTomMath is a library that provides multiple-precision
* integer arithmetic as well as number theoretic functionality.
*
* The library was designed directly after the MPI library by
* Michael Fromberger but has been written from scratch with
* additional optimizations in place.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tstdenis82@gmail.com, http://libtom.org
*/
static const int lnz[16] = {
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
};
/* Counts the number of lsbs which are zero before the first zero bit */
int mp_cnt_lsb(mp_int *a) {
int x;
mp_digit q, qq;
/* easy out */
if (mp_iszero(a) == MP_YES) {
return 0;
}
/* scan lower digits until non-zero */
for (x = 0; (x < a->used) && (a->dp[x] == 0); x++) {
}
q = a->dp[x];
x *= DIGIT_BIT;
/* now scan this digit until a 1 is found */
if ((q & 1) == 0) {
do {
qq = q & 15;
x += lnz[qq];
q >>= 4;
} while (qq == 0);
}
return x;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
#ifdef BN_MP_COPY_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
* LibTomMath is a library that provides multiple-precision
* integer arithmetic as well as number theoretic functionality.
*
* The library was designed directly after the MPI library by
* Michael Fromberger but has been written from scratch with
* additional optimizations in place.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tstdenis82@gmail.com, http://libtom.org
*/
/* copy, b = a */
int
mp_copy(mp_int *a, mp_int *b) {
int res, n;
/* if dst == src do nothing */
if (a == b) {
return MP_OKAY;
}
/* grow dest */
if (b->alloc < a->used) {
if ((res = mp_grow(b, a->used)) != MP_OKAY) {
return res;
}
}
/* zero b and copy the parameters over */
{
mp_digit *tmpa, *tmpb;
/* pointer aliases */
/* source */
tmpa = a->dp;
/* destination */
tmpb = b->dp;
/* copy all the digits */
for (n = 0; n < a->used; n++) {
*tmpb++ = *tmpa++;
}
/* clear high digits */
for ( ; n < b->used; n++) {
*tmpb++ = 0;
}
}
/* copy used count and sign */
b->used = a->used;
b->sign = a->sign;
return MP_OKAY;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
#ifdef BN_MP_COUNT_BITS_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
* LibTomMath is a library that provides multiple-precision
* integer arithmetic as well as number theoretic functionality.
*
* The library was designed directly after the MPI library by
* Michael Fromberger but has been written from scratch with
* additional optimizations in place.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tstdenis82@gmail.com, http://libtom.org
*/
/* returns the number of bits in an int */
int
mp_count_bits(mp_int *a) {
int r;
mp_digit q;
/* shortcut */
if (a->used == 0) {
return 0;
}
/* get number of digits and add that */
r = (a->used - 1) * DIGIT_BIT;
/* take the last digit and count the bits in it */
q = a->dp[a->used - 1];
while (q > ((mp_digit)0)) {
++r;
q >>= ((mp_digit)1);
}
return r;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
#ifdef BN_MP_DIV_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
* LibTomMath is a library that provides multiple-precision
* integer arithmetic as well as number theoretic functionality.
*
* The library was designed directly after the MPI library by
* Michael Fromberger but has been written from scratch with
* additional optimizations in place.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tstdenis82@gmail.com, http://libtom.org
*/
#ifdef BN_MP_DIV_SMALL
/* slower bit-bang division... also smaller */
int mp_div(mp_int *a, mp_int *b, mp_int *c, mp_int *d) {
mp_int ta, tb, tq, q;
int res, n, n2;
/* is divisor zero ? */
if (mp_iszero(b) == MP_YES) {
return MP_VAL;
}
/* if a < b then q=0, r = a */
if (mp_cmp_mag(a, b) == MP_LT) {
if (d != NULL) {
res = mp_copy(a, d);
} else {
res = MP_OKAY;
}
if (c != NULL) {
mp_zero(c);
}
return res;
}
/* init our temps */
if ((res = mp_init_multi(&ta, &tb, &tq, &q, NULL)) != MP_OKAY) {
return res;
}
mp_set(&tq, 1);
n = mp_count_bits(a) - mp_count_bits(b);
if (((res = mp_abs(a, &ta)) != MP_OKAY) ||
((res = mp_abs(b, &tb)) != MP_OKAY) ||
((res = mp_mul_2d(&tb, n, &tb)) != MP_OKAY) ||
((res = mp_mul_2d(&tq, n, &tq)) != MP_OKAY)) {
goto LBL_ERR;
}
while (n-- >= 0) {
if (mp_cmp(&tb, &ta) != MP_GT) {
if (((res = mp_sub(&ta, &tb, &ta)) != MP_OKAY) ||
((res = mp_add(&q, &tq, &q)) != MP_OKAY)) {
goto LBL_ERR;
}
}
if (((res = mp_div_2d(&tb, 1, &tb, NULL)) != MP_OKAY) ||
((res = mp_div_2d(&tq, 1, &tq, NULL)) != MP_OKAY)) {
goto LBL_ERR;
}
}
/* now q == quotient and ta == remainder */
n = a->sign;
n2 = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
if (c != NULL) {
mp_exch(c, &q);
c->sign = (mp_iszero(c) == MP_YES) ? MP_ZPOS : n2;
}
if (d != NULL) {
mp_exch(d, &ta);
d->sign = (mp_iszero(d) == MP_YES) ? MP_ZPOS : n;
}
LBL_ERR:
mp_clear_multi(&ta, &tb, &tq, &q, NULL);
return res;
}
#else
/* integer signed division.
* c*b + d == a [e.g. a/b, c=quotient, d=remainder]
* HAC pp.598 Algorithm 14.20
*
* Note that the description in HAC is horribly
* incomplete. For example, it doesn't consider
* the case where digits are removed from 'x' in
* the inner loop. It also doesn't consider the
* case that y has fewer than three digits, etc..
*
* The overall algorithm is as described as
* 14.20 from HAC but fixed to treat these cases.
*/
int mp_div(mp_int *a, mp_int *b, mp_int *c, mp_int *d) {
mp_int q, x, y, t1, t2;
int res, n, t, i, norm, neg;
/* is divisor zero ? */
if (mp_iszero(b) == MP_YES) {
return MP_VAL;
}
/* if a < b then q=0, r = a */
if (mp_cmp_mag(a, b) == MP_LT) {
if (d != NULL) {
res = mp_copy(a, d);
} else {
res = MP_OKAY;
}
if (c != NULL) {
mp_zero(c);
}
return res;
}
if ((res = mp_init_size(&q, a->used + 2)) != MP_OKAY) {
return res;
}
q.used = a->used + 2;
if ((res = mp_init(&t1)) != MP_OKAY) {
goto LBL_Q;
}
if ((res = mp_init(&t2)) != MP_OKAY) {
goto LBL_T1;
}
if ((res = mp_init_copy(&x, a)) != MP_OKAY) {
goto LBL_T2;
}
if ((res = mp_init_copy(&y, b)) != MP_OKAY) {
goto LBL_X;
}
/* fix the sign */
neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
x.sign = y.sign = MP_ZPOS;
/* normalize both x and y, ensure that y >= b/2, [b == 2**DIGIT_BIT] */
norm = mp_count_bits(&y) % DIGIT_BIT;
if (norm < (int)(DIGIT_BIT - 1)) {
norm = (DIGIT_BIT - 1) - norm;
if ((res = mp_mul_2d(&x, norm, &x)) != MP_OKAY) {
goto LBL_Y;
}
if ((res = mp_mul_2d(&y, norm, &y)) != MP_OKAY) {
goto LBL_Y;
}
} else {
norm = 0;
}
/* note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4 */
n = x.used - 1;
t = y.used - 1;
/* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */
if ((res = mp_lshd(&y, n - t)) != MP_OKAY) { /* y = y*b**{n-t} */
goto LBL_Y;
}
while (mp_cmp(&x, &y) != MP_LT) {
++(q.dp[n - t]);
if ((res = mp_sub(&x, &y, &x)) != MP_OKAY) {
goto LBL_Y;
}
}
/* reset y by shifting it back down */
mp_rshd(&y, n - t);
/* step 3. for i from n down to (t + 1) */
for (i = n; i >= (t + 1); i--) {
if (i > x.used) {
continue;
}
/* step 3.1 if xi == yt then set q{i-t-1} to b-1,
* otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */
if (x.dp[i] == y.dp[t]) {
q.dp[(i - t) - 1] = ((((mp_digit)1) << DIGIT_BIT) - 1);
} else {
mp_word tmp;
tmp = ((mp_word)x.dp[i]) << ((mp_word)DIGIT_BIT);
tmp |= ((mp_word)x.dp[i - 1]);
tmp /= ((mp_word)y.dp[t]);
if (tmp > (mp_word)MP_MASK) {
tmp = MP_MASK;
}
q.dp[(i - t) - 1] = (mp_digit)(tmp & (mp_word)(MP_MASK));
}
/* while (q{i-t-1} * (yt * b + y{t-1})) >
xi * b**2 + xi-1 * b + xi-2
do q{i-t-1} -= 1;
*/
q.dp[(i - t) - 1] = (q.dp[(i - t) - 1] + 1) & MP_MASK;
do {
q.dp[(i - t) - 1] = (q.dp[(i - t) - 1] - 1) & MP_MASK;
/* find left hand */
mp_zero(&t1);
t1.dp[0] = ((t - 1) < 0) ? 0 : y.dp[t - 1];
t1.dp[1] = y.dp[t];
t1.used = 2;
if ((res = mp_mul_d(&t1, q.dp[(i - t) - 1], &t1)) != MP_OKAY) {
goto LBL_Y;
}
/* find right hand */
t2.dp[0] = ((i - 2) < 0) ? 0 : x.dp[i - 2];
t2.dp[1] = ((i - 1) < 0) ? 0 : x.dp[i - 1];
t2.dp[2] = x.dp[i];
t2.used = 3;
} while (mp_cmp_mag(&t1, &t2) == MP_GT);
/* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */
if ((res = mp_mul_d(&y, q.dp[(i - t) - 1], &t1)) != MP_OKAY) {
goto LBL_Y;
}
if ((res = mp_lshd(&t1, (i - t) - 1)) != MP_OKAY) {
goto LBL_Y;
}
if ((res = mp_sub(&x, &t1, &x)) != MP_OKAY) {
goto LBL_Y;
}
/* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */
if (x.sign == MP_NEG) {
if ((res = mp_copy(&y, &t1)) != MP_OKAY) {
goto LBL_Y;
}
if ((res = mp_lshd(&t1, (i - t) - 1)) != MP_OKAY) {
goto LBL_Y;
}
if ((res = mp_add(&x, &t1, &x)) != MP_OKAY) {
goto LBL_Y;
}
q.dp[(i - t) - 1] = (q.dp[(i - t) - 1] - 1UL) & MP_MASK;
}
}
/* now q is the
gitextract_ym8tj97v/ ├── .gitignore ├── CHANGELOG.md ├── README.md ├── carl.1 ├── carl.c ├── carl.md ├── carl_mpw.sit.hqx ├── cryanc.c ├── cryanc.h └── debughello
SYMBOL INDEX (1034 symbols across 3 files)
FILE: carl.c
function error (line 42) | void error(char *msg, int code) {
function timeout (line 57) | void timeout() { /* portable enough */
function stdin_pending (line 73) | int stdin_pending() {
function mac_connect (line 95) | void mac_connect(int sockfd, struct sockaddr *s, int ssize, char *err, i...
function https_send_pending (line 120) | int https_send_pending(int client_sock, struct TLSContext *context) {
function validate_certificate (line 139) | int validate_certificate(struct TLSContext *context, struct TLSCertifica...
function scheme_is (line 153) | int scheme_is(char *url, char *scheme) {
function help (line 222) | void help(int longdesc, char *me) {
function main (line 249) | int main(int argc, char *argv[]) {
FILE: cryanc.c
type u_int64_t (line 191) | typedef unsigned long long u_int64_t;
function usleep (line 249) | int usleep(unsigned int useconds)
function __short (line 428) | void __short(void *where, unsigned int index, unsigned short value) {
function __llong (line 437) | void __llong(void *where, uint64_t value) {
type u_int8_t (line 496) | typedef u_int8_t uint8_t;
type u_int16_t (line 497) | typedef u_int16_t uint16_t;
type u_int32_t (line 498) | typedef u_int32_t uint32_t;
type u_int64_t (line 499) | typedef u_int64_t uint64_t;
type mp_digit (line 2744) | typedef uint8_t mp_digit;
type mp_word (line 2745) | typedef uint16_t mp_word;
type mp_digit (line 2751) | typedef uint16_t mp_digit;
type mp_word (line 2752) | typedef uint32_t mp_word;
type ulong64 (line 2760) | typedef unsigned long long ulong64;
type long64 (line 2761) | typedef signed long long long64;
type mp_digit (line 2764) | typedef uint64_t mp_digit;
type mp_word (line 2766) | typedef unsigned __int128 mp_word;
type mp_word (line 2768) | typedef unsigned long mp_word __attribute__ ((mode(TI)));
type uint128_t (line 2773) | typedef uint128_t mp_word;
type ulong64 (line 2782) | typedef unsigned long long ulong64;
type long64 (line 2783) | typedef signed long long long64;
type mp_digit (line 2786) | typedef uint32_t mp_digit;
type mp_word (line 2787) | typedef uint64_t mp_word;
type uint_least32_t (line 2802) | typedef uint_least32_t mp_min_u32;
type mp_digit (line 2804) | typedef mp_digit mp_min_u32;
type mp_err (line 2835) | typedef int mp_err;
type mp_int (line 2859) | typedef struct {
type aarc4_stream (line 3279) | struct aarc4_stream {
type aarc4_stream (line 3285) | struct aarc4_stream
function aarc4_init (line 3289) | static void
function aarc4_addrandom (line 3298) | static void
function aarc4_getbyte (line 3313) | static uint8_t
function aarc4_getword (line 3325) | static uint32_t
function aarc4_stir (line 3335) | static void
function aarc4random_stir (line 3375) | void
function aarc4random_addrandom (line 3384) | void
function aarc4random_maybe (line 3391) | uint32_t
function aarc4random_batch_maybe (line 3403) | size_t
function fast_mp_invmod (line 3565) | int fast_mp_invmod(mp_int *a, mp_int *b, mp_int *c) {
function fast_mp_montgomery_reduce (line 3717) | int fast_mp_montgomery_reduce(mp_int *x, mp_int *n, mp_digit rho) {
function fast_s_mp_mul_digs (line 3899) | int fast_s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs) {
function fast_s_mp_mul_high_digs (line 4000) | int fast_s_mp_mul_high_digs(mp_int *a, mp_int *b, mp_int *c, int digs) {
function fast_s_mp_sqr (line 4101) | int fast_s_mp_sqr(mp_int *a, mp_int *b) {
function mp_2expt (line 4212) | int
function mp_abs (line 4261) | int
function mp_add (line 4303) | int mp_add(mp_int *a, mp_int *b, mp_int *c) {
function mp_add_d (line 4357) | int
function mp_addmod (line 4470) | int
function mp_and (line 4513) | int
function mp_clamp (line 4578) | void
function mp_clear (line 4618) | void
function mp_clear_multi (line 4663) | void mp_clear_multi(mp_int *mp, ...) {
function mp_cmp (line 4700) | int
function mp_cmp_d (line 4745) | int mp_cmp_d(mp_int *a, mp_digit b) {
function mp_cmp_mag (line 4791) | int mp_cmp_mag(mp_int *a, mp_int *b) {
function mp_cnt_lsb (line 4852) | int mp_cnt_lsb(mp_int *a) {
function mp_copy (line 4903) | int
function mp_count_bits (line 4973) | int
function mp_div (line 5022) | int mp_div(mp_int *a, mp_int *b, mp_int *c, mp_int *d) {
function mp_div (line 5103) | int mp_div(mp_int *a, mp_int *b, mp_int *c, mp_int *d) {
function mp_div_2 (line 5314) | int mp_div_2(mp_int *a, mp_int *b) {
function mp_div_2d (line 5384) | int mp_div_2d(mp_int *a, int b, mp_int *c, mp_int *d) {
function mp_div_3 (line 5483) | int
function s_is_power_of_two (line 5562) | static int s_is_power_of_two(mp_digit b, int *p) {
function mp_div_d (line 5580) | int mp_div_d(mp_int *a, mp_digit b, mp_int *c, mp_digit *d) {
function mp_dr_is_modulus (line 5678) | int mp_dr_is_modulus(mp_int *a) {
function mp_dr_reduce (line 5735) | int
function mp_dr_setup (line 5820) | void mp_dr_setup(mp_int *a, mp_digit *d) {
function mp_exch (line 5855) | void
function mp_export (line 5891) | int mp_export(void *rop, size_t *countp, int order, size_t size,
function mp_expt_d (line 5979) | int mp_expt_d(mp_int *a, mp_digit b, mp_int *c) {
function mp_expt_d_ex (line 6008) | int mp_expt_d_ex(mp_int *a, mp_digit b, mp_int *c, int fast) {
function mp_exptmod_fast (line 6218) | int mp_exptmod_fast(mp_int *G, mp_int *X, mp_int *P, mp_int *Y, int redm...
function mp_exteuclid (line 6530) | int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U...
function mp_fread (line 6654) | int mp_fread(mp_int *a, int radix, FILE *stream) {
function mp_fwrite (line 6721) | int mp_fwrite(mp_int *a, int radix, FILE *stream) {
function mp_gcd (line 6775) | int mp_gcd(mp_int *a, mp_int *b, mp_int *c) {
function mp_get_int (line 6882) | unsigned long mp_get_int(mp_int *a) {
function mp_get_long (line 6929) | unsigned long mp_get_long(mp_int *a) {
function mp_get_long_long (line 6972) | unsigned long long mp_get_long_long(mp_int *a) {
function mp_grow (line 7015) | int mp_grow(mp_int *a, int size) {
function mp_import (line 7076) | int mp_import(mp_int *rop, size_t count, int order, size_t size,
function mp_init (line 7149) | int mp_init(mp_int *a) {
function mp_init_copy (line 7197) | int mp_init_copy(mp_int *a, mp_int *b) {
function mp_init_multi (line 7230) | int mp_init_multi(mp_int *mp, ...) {
function mp_init_set (line 7290) | int mp_init_set(mp_int *a, mp_digit b) {
function mp_init_set_int (line 7325) | int mp_init_set_int(mp_int *a, unsigned long b) {
function mp_init_size (line 7359) | int mp_init_size(mp_int *a, int size) {
function mp_invmod (line 7409) | int mp_invmod(mp_int *a, mp_int *b, mp_int *c) {
function mp_invmod_slow (line 7454) | int mp_invmod_slow(mp_int *a, mp_int *b, mp_int *c) {
function mp_is_square (line 7653) | int mp_is_square(mp_int *arg, int *ret) {
function mp_jacobi (line 7747) | int mp_jacobi(mp_int *a, mp_int *n, int *c) {
function mp_karatsuba_mul (line 7885) | int mp_karatsuba_mul(mp_int *a, mp_int *b, mp_int *c) {
function mp_karatsuba_sqr (line 8032) | int mp_karatsuba_sqr(mp_int *a, mp_int *b) {
function mp_lcm (line 8149) | int mp_lcm(mp_int *a, mp_int *b, mp_int *c) {
function mp_lshd (line 8211) | int mp_lshd(mp_int *a, int b) {
function mp_mod (line 8280) | int
function mp_mod_2d (line 8330) | int
function mp_mod_d (line 8386) | int
function mp_montgomery_calc_normalization (line 8421) | int mp_montgomery_calc_normalization(mp_int *a, mp_int *b) {
function mp_montgomery_reduce (line 8477) | int
function mp_montgomery_setup (line 8597) | int
function mp_mul (line 8658) | int mp_mul(mp_int *a, mp_int *b, mp_int *c) {
function mp_mul_2 (line 8728) | int mp_mul_2(mp_int *a, mp_int *b) {
function mp_mul_2d (line 8811) | int mp_mul_2d(mp_int *a, int b, mp_int *c) {
function mp_mul_d (line 8898) | int
function mp_mulmod (line 8979) | int mp_mulmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d) {
function mp_n_root (line 9023) | int mp_n_root(mp_int *a, mp_digit b, mp_int *c) {
function mp_n_root_ex (line 9061) | int mp_n_root_ex(mp_int *a, mp_digit b, mp_int *c, int fast) {
function mp_neg (line 9186) | int mp_neg(mp_int *a, mp_int *b) {
function mp_or (line 9229) | int mp_or(mp_int *a, mp_int *b, mp_int *c) {
function mp_prime_fermat (line 9288) | int mp_prime_fermat(mp_int *a, mp_int *b, int *result) {
function mp_prime_is_divisible (line 9349) | int mp_prime_is_divisible(mp_int *a, int *result) {
function mp_prime_is_prime (line 9403) | int mp_prime_is_prime(mp_int *a, int t, int *result) {
function mp_prime_miller_rabin (line 9488) | int mp_prime_miller_rabin(mp_int *a, mp_int *b, int *result) {
function mp_prime_next_prime (line 9591) | int mp_prime_next_prime(mp_int *a, int t, int bbs_style) {
function mp_prime_rabin_miller_trials (line 9774) | int mp_prime_rabin_miller_trials(int size) {
function mp_prime_random_ex (line 9826) | int mp_prime_random_ex(mp_int *a, int t, int size, int flags, ltm_prime_...
function mp_radix_size (line 9950) | int mp_radix_size(mp_int *a, int radix, int *size) {
function mp_rand (line 10056) | int
function mp_read_radix (line 10113) | int mp_read_radix(mp_int *a, const char *str, int radix) {
function mp_read_signed_bin (line 10200) | int mp_read_signed_bin(mp_int *a, const unsigned char *b, int c) {
function mp_read_unsigned_bin (line 10243) | int mp_read_unsigned_bin(mp_int *a, const unsigned char *b, int c) {
function mp_reduce (line 10303) | int mp_reduce(mp_int *x, mp_int *m, mp_int *mu) {
function mp_reduce_2k (line 10402) | int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d) {
function mp_reduce_2k_l (line 10469) | int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d) {
function mp_reduce_2k_setup (line 10531) | int mp_reduce_2k_setup(mp_int *a, mp_digit *d) {
function mp_reduce_2k_setup_l (line 10580) | int mp_reduce_2k_setup_l(mp_int *a, mp_int *d) {
function mp_reduce_is_2k (line 10626) | int mp_reduce_is_2k(mp_int *a) {
function mp_reduce_is_2k_l (line 10679) | int mp_reduce_is_2k_l(mp_int *a) {
function mp_reduce_setup (line 10725) | int mp_reduce_setup(mp_int *a, mp_int *b) {
function mp_rshd (line 10759) | void mp_rshd(mp_int *a, int b) {
function mp_set (line 10833) | void mp_set(mp_int *a, mp_digit b) {
function mp_set_int (line 10864) | int mp_set_int(mp_int *a, unsigned long b) {
function mp_shrink (line 10968) | int mp_shrink(mp_int *a) {
function mp_signed_bin_size (line 11011) | int mp_signed_bin_size(mp_int *a) {
function mp_sqr (line 11040) | int
function mp_sqrmod (line 11102) | int
function mp_sqrt (line 11145) | int mp_sqrt(mp_int *arg, mp_int *ret) {
function mp_sqrtmod_prime (line 11226) | int mp_sqrtmod_prime(mp_int *n, mp_int *prime, mp_int *ret) {
function mp_sub (line 11352) | int
function mp_sub_d (line 11412) | int
function mp_submod (line 11506) | int
function mp_to_signed_bin (line 11550) | int mp_to_signed_bin(mp_int *a, unsigned char *b) {
function mp_to_signed_bin_n (line 11585) | int mp_to_signed_bin_n(mp_int *a, unsigned char *b, unsigned long *outle...
function mp_to_unsigned_bin (line 11618) | int mp_to_unsigned_bin(mp_int *a, unsigned char *b) {
function mp_toom_mul (line 11674) | int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c) {
function mp_toom_sqr (line 11955) | int
function mp_toradix (line 12184) | int mp_toradix(mp_int *a, char *str, int radix) {
function mp_unsigned_bin_size (line 12260) | int mp_unsigned_bin_size(mp_int *a) {
function mp_xor (line 12291) | int
function mp_zero (line 12344) | void mp_zero(mp_int *a) {
function bn_reverse (line 12446) | void
function s_mp_add (line 12487) | int
function s_mp_exptmod (line 12597) | int s_mp_exptmod(mp_int *G, mp_int *X, mp_int *P, mp_int *Y, int redmode) {
function s_mp_mul_digs (line 12851) | int s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs) {
function s_mp_mul_high_digs (line 12942) | int
function s_mp_sqr (line 13023) | int s_mp_sqr(mp_int *a, mp_int *b) {
function s_mp_sub (line 13109) | int
function crypt_argchk (line 13611) | void crypt_argchk(char *v, char *s, int d) {
type ulong64 (line 14226) | typedef unsigned __int64 ulong64;
type ulong64 (line 14229) | typedef unsigned long long ulong64;
type ulong32 (line 14236) | typedef unsigned ulong32;
type ulong32 (line 14238) | typedef unsigned long ulong32;
function ROL (line 14464) | static inline unsigned ROL(unsigned word, int i) {
function ROR (line 14471) | static inline unsigned ROR(unsigned word, int i) {
function ROLc (line 14480) | static inline unsigned ROLc(unsigned word, const int i) {
function RORc (line 14487) | static inline unsigned RORc(unsigned word, const int i) {
function ROL (line 14502) | static inline unsigned ROL(unsigned word, int i) {
function ROR (line 14509) | static inline unsigned ROR(unsigned word, int i) {
function ROLc (line 14518) | static inline unsigned ROLc(unsigned word, const int i) {
function RORc (line 14525) | static inline unsigned RORc(unsigned word, const int i) {
function ROL64 (line 14552) | static inline unsigned long ROL64(unsigned long word, int i) {
function ROR64 (line 14559) | static inline unsigned long ROR64(unsigned long word, int i) {
function ROL64c (line 14568) | static inline unsigned long ROL64c(unsigned long word, const int i) {
function ROR64c (line 14575) | static inline unsigned long ROR64c(unsigned long word, const int i) {
type blowfish_key (line 14632) | struct blowfish_key {
type rc5_key (line 14639) | struct rc5_key {
type rc6_key (line 14646) | struct rc6_key {
type saferp_key (line 14652) | struct saferp_key {
type rijndael_key (line 14659) | struct rijndael_key {
type kseed_key (line 14666) | struct kseed_key {
type kasumi_key (line 14672) | struct kasumi_key {
type xtea_key (line 14680) | struct xtea_key {
type twofish_key (line 14687) | struct twofish_key {
type twofish_key (line 14691) | struct twofish_key {
type safer_key (line 14708) | struct safer_key {
type rc2_key (line 14714) | struct rc2_key {
type des_key (line 14720) | struct des_key {
type des3_key (line 14724) | struct des3_key {
type cast5_key (line 14730) | struct cast5_key {
type noekeon_key (line 14736) | struct noekeon_key {
type skipjack_key (line 14742) | struct skipjack_key {
type khazad_key (line 14748) | struct khazad_key {
type anubis_key (line 14755) | struct anubis_key {
type multi2_key (line 14764) | struct multi2_key {
type symmetric_key (line 14770) | typedef union Symmetric_key {
type symmetric_ECB (line 14831) | typedef struct {
type symmetric_CFB (line 14843) | typedef struct {
type symmetric_OFB (line 14861) | typedef struct {
type symmetric_CBC (line 14877) | typedef struct {
type symmetric_CTR (line 14892) | typedef struct {
type symmetric_LRW (line 14916) | typedef struct {
type symmetric_F8 (line 14941) | typedef struct {
type ltc_cipher_descriptor (line 14960) | struct ltc_cipher_descriptor {
type ltc_cipher_descriptor (line 15190) | struct ltc_cipher_descriptor
type ltc_cipher_descriptor (line 15201) | struct ltc_cipher_descriptor
type ltc_cipher_descriptor (line 15212) | struct ltc_cipher_descriptor
type ltc_cipher_descriptor (line 15223) | struct ltc_cipher_descriptor
type ltc_cipher_descriptor (line 15234) | struct ltc_cipher_descriptor
type ltc_cipher_descriptor (line 15251) | struct ltc_cipher_descriptor
type ltc_cipher_descriptor (line 15279) | struct ltc_cipher_descriptor
type ltc_cipher_descriptor (line 15280) | struct ltc_cipher_descriptor
type ltc_cipher_descriptor (line 15291) | struct ltc_cipher_descriptor
type ltc_cipher_descriptor (line 15302) | struct ltc_cipher_descriptor
type ltc_cipher_descriptor (line 15319) | struct ltc_cipher_descriptor
type ltc_cipher_descriptor (line 15330) | struct ltc_cipher_descriptor
type ltc_cipher_descriptor (line 15341) | struct ltc_cipher_descriptor
type ltc_cipher_descriptor (line 15352) | struct ltc_cipher_descriptor
type ltc_cipher_descriptor (line 15363) | struct ltc_cipher_descriptor
type ltc_cipher_descriptor (line 15374) | struct ltc_cipher_descriptor
type ltc_cipher_descriptor (line 15385) | struct ltc_cipher_descriptor
type ltc_cipher_descriptor (line 15396) | struct ltc_cipher_descriptor
type ltc_cipher_descriptor (line 15408) | struct ltc_cipher_descriptor
type symmetric_xts (line 15504) | typedef struct {
type ltc_cipher_descriptor (line 15535) | struct ltc_cipher_descriptor
type ltc_cipher_descriptor (line 15536) | struct ltc_cipher_descriptor
type sha512_state (line 15548) | struct sha512_state {
type sha256_state (line 15556) | struct sha256_state {
type sha1_state (line 15564) | struct sha1_state {
type md5_state (line 15572) | struct md5_state {
type md4_state (line 15580) | struct md4_state {
type tiger_state (line 15588) | struct tiger_state {
type md2_state (line 15596) | struct md2_state {
type rmd128_state (line 15603) | struct rmd128_state {
type rmd160_state (line 15611) | struct rmd160_state {
type rmd256_state (line 15619) | struct rmd256_state {
type rmd320_state (line 15627) | struct rmd320_state {
type whirlpool_state (line 15635) | struct whirlpool_state {
type chc_state (line 15643) | struct chc_state {
type hash_state (line 15650) | typedef union Hash_state {
type ltc_hash_descriptor (line 15695) | struct ltc_hash_descriptor {
type ltc_hash_descriptor (line 15748) | struct ltc_hash_descriptor
type ltc_hash_descriptor (line 15757) | struct ltc_hash_descriptor
type ltc_hash_descriptor (line 15766) | struct ltc_hash_descriptor
type ltc_hash_descriptor (line 15779) | struct ltc_hash_descriptor
type ltc_hash_descriptor (line 15788) | struct ltc_hash_descriptor
type ltc_hash_descriptor (line 15800) | struct ltc_hash_descriptor
type ltc_hash_descriptor (line 15810) | struct ltc_hash_descriptor
type ltc_hash_descriptor (line 15819) | struct ltc_hash_descriptor
type ltc_hash_descriptor (line 15828) | struct ltc_hash_descriptor
type ltc_hash_descriptor (line 15837) | struct ltc_hash_descriptor
type ltc_hash_descriptor (line 15846) | struct ltc_hash_descriptor
type ltc_hash_descriptor (line 15855) | struct ltc_hash_descriptor
type ltc_hash_descriptor (line 15864) | struct ltc_hash_descriptor
type ltc_hash_descriptor (line 15873) | struct ltc_hash_descriptor
type ltc_hash_descriptor (line 15882) | struct ltc_hash_descriptor
type ltc_hash_descriptor (line 15890) | struct ltc_hash_descriptor
type ltc_hash_descriptor (line 15891) | struct ltc_hash_descriptor
type hmac_state (line 15946) | typedef struct Hmac_state {
type omac_state (line 15972) | typedef struct {
type pmac_state (line 16002) | typedef struct {
type eax_state (line 16048) | typedef struct {
type ocb_state (line 16084) | typedef struct {
type yarrow_prng (line 16324) | struct yarrow_prng {
function find_cipher_id (line 17934) | int find_cipher_id(unsigned char ID) {
function find_hash (line 17976) | int find_hash(const char *name) {
function find_hash_any (line 18018) | int find_hash_any(const char *name, int digestlen) {
function find_hash_id (line 18069) | int find_hash_id(unsigned char ID) {
function find_hash_oid (line 18106) | int find_hash_oid(const unsigned long *ID, unsigned long IDlen) {
function find_prng (line 18148) | int find_prng(const char *name) {
function crypt_fsa (line 18186) | int crypt_fsa(void *mp, ...) {
type ltc_hash_descriptor (line 18243) | struct ltc_hash_descriptor
function hash_is_valid (line 18247) | LTC_MUTEX_GLOBAL(ltc_hash_mutex)
type ltc_prng_descriptor (line 18323) | struct ltc_prng_descriptor
function prng_is_valid (line 18327) | LTC_MUTEX_GLOBAL(ltc_prng_mutex)
function register_cipher (line 18394) | int register_cipher(const struct ltc_cipher_descriptor *cipher) {
function register_hash (line 18449) | int register_hash(const struct ltc_hash_descriptor *hash) {
function register_prng (line 18504) | int register_prng(const struct ltc_prng_descriptor *prng) {
function unregister_cipher (line 18559) | int unregister_cipher(const struct ltc_cipher_descriptor *cipher) {
function unregister_hash (line 18605) | int unregister_hash(const struct ltc_hash_descriptor *hash) {
function unregister_prng (line 18650) | int unregister_prng(const struct ltc_prng_descriptor *prng) {
function der_decode_bit_string (line 18701) | int der_decode_bit_string(const unsigned char *in, unsigned long inlen,
function der_decode_boolean (line 18802) | int der_decode_boolean(const unsigned char *in, unsigned long inlen,
function der_decode_choice (line 18849) | int der_decode_choice(const unsigned char *in, unsigned long *inlen,
function der_decode_ia5_string (line 19032) | int der_decode_ia5_string(const unsigned char *in, unsigned long inlen,
function der_decode_integer (line 19127) | int der_decode_integer(const unsigned char *in, unsigned long inlen, voi...
function der_decode_object_identifier (line 19236) | int der_decode_object_identifier(const unsigned char *in, unsigned long ...
function der_decode_octet_string (line 19337) | int der_decode_octet_string(const unsigned char *in, unsigned long inlen,
function der_decode_printable_string (line 19428) | int der_decode_printable_string(const unsigned char *in, unsigned long i...
function der_decode_sequence_ex (line 19525) | int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen,
function fetch_length (line 19829) | static unsigned long fetch_length(const unsigned char *in, unsigned long...
function der_decode_sequence_flexi (line 19873) | int der_decode_sequence_flexi(const unsigned char *in, unsigned long *in...
function der_decode_sequence_multi (line 20227) | int der_decode_sequence_multi(const unsigned char *in, unsigned long inl...
function der_decode_short_integer (line 20365) | int der_decode_short_integer(const unsigned char *in, unsigned long inle...
function char_to_int (line 20424) | static int char_to_int(unsigned char x) {
function der_decode_utctime (line 20471) | int der_decode_utctime(const unsigned char *in, unsigned long *inlen,
function der_decode_utf8_string (line 20578) | int der_decode_utf8_string(const unsigned char *in, unsigned long inlen,
function der_encode_bit_string (line 20691) | int der_encode_bit_string(const unsigned char *in, unsigned long inlen,
function der_encode_boolean (line 20779) | int der_encode_boolean(int in,
function der_encode_ia5_string (line 20830) | int der_encode_ia5_string(const unsigned char *in, unsigned long inlen,
function der_encode_integer (line 20917) | int der_encode_integer(void *num, unsigned char *out, unsigned long *out...
function der_encode_object_identifier (line 21046) | int der_encode_object_identifier(unsigned long *words, unsigned long nwo...
function der_encode_octet_string (line 21161) | int der_encode_octet_string(const unsigned char *in, unsigned long inlen,
function der_encode_printable_string (line 21246) | int der_encode_printable_string(const unsigned char *in, unsigned long i...
function der_encode_sequence_ex (line 21333) | int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen,
function der_encode_sequence_multi (line 21665) | int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen,...
function ltc_to_asn1 (line 21795) | static int ltc_to_asn1(int v) {
function qsort_helper_set (line 21840) | static int qsort_helper_set(const void *a, const void *b) {
function der_encode_set (line 21863) | int der_encode_set(ltc_asn1_list *list, unsigned long inlen,
type edge (line 21918) | struct edge {
function qsort_helper (line 21923) | static int qsort_helper(const void *a, const void *b) {
function der_encode_setof (line 21958) | int der_encode_setof(ltc_asn1_list *list, unsigned long inlen,
function der_encode_short_integer (line 22087) | int der_encode_short_integer(unsigned long num, unsigned char *out, unsi...
function der_encode_utctime (line 22189) | int der_encode_utctime(ltc_utctime *utctime,
function der_encode_utf8_string (line 22268) | int der_encode_utf8_string(const wchar_t *in, unsigned long inlen,
function der_length_bit_string (line 22387) | int der_length_bit_string(unsigned long nbits, unsigned long *outlen) {
function der_length_boolean (line 22442) | int der_length_boolean(unsigned long *outlen) {
function der_ia5_char_encode (line 22580) | int der_ia5_char_encode(int c) {
function der_ia5_value_decode (line 22591) | int der_ia5_value_decode(int v) {
function der_length_ia5_string (line 22609) | int der_length_ia5_string(const unsigned char *octets, unsigned long noc...
function der_length_integer (line 22674) | int der_length_integer(void *num, unsigned long *outlen) {
function der_object_identifier_bits (line 22750) | unsigned long der_object_identifier_bits(unsigned long x) {
function der_length_object_identifier (line 22769) | int der_length_object_identifier(unsigned long *words, unsigned long nwo...
function der_length_octet_string (line 22844) | int der_length_octet_string(unsigned long noctets, unsigned long *outlen) {
function der_printable_char_encode (line 22971) | int der_printable_char_encode(int c) {
function der_printable_value_decode (line 22982) | int der_printable_value_decode(int v) {
function der_length_printable_string (line 23000) | int der_length_printable_string(const unsigned char *octets, unsigned lo...
function der_length_sequence (line 23065) | int der_length_sequence(ltc_asn1_list *list, unsigned long inlen,
function der_length_short_integer (line 23234) | int der_length_short_integer(unsigned long num, unsigned long *outlen) {
function der_length_utctime (line 23304) | int der_length_utctime(ltc_utctime *utctime, unsigned long *outlen) {
function der_utf8_charsize (line 23348) | unsigned long der_utf8_charsize(const wchar_t c) {
function der_length_utf8_string (line 23367) | int der_length_utf8_string(const wchar_t *in, unsigned long noctets, uns...
function der_sequence_free (line 23430) | void der_sequence_free(ltc_asn1_list *in) {
function ecc_ansi_x963_export (line 23651) | int ecc_ansi_x963_export(ecc_key *key, unsigned char *out, unsigned long...
function ecc_ansi_x963_import (line 23722) | int ecc_ansi_x963_import(const unsigned char *in, unsigned long inlen, e...
function ecc_ansi_x963_import_ex (line 23726) | int ecc_ansi_x963_import_ex(const unsigned char *in, unsigned long inlen...
function ecc_decrypt_key (line 23831) | int ecc_decrypt_key(const unsigned char *in, unsigned long inlen,
function ecc_encrypt_key (line 23983) | int ecc_encrypt_key(const unsigned char *in, unsigned long inlen,
function ecc_export (line 24114) | int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_...
function ecc_free (line 24191) | void ecc_free(ecc_key *key) {
function ecc_get_size (line 24231) | int ecc_get_size(ecc_key *key) {
function is_point (line 24269) | static int is_point(ecc_key *key) {
function ecc_import (line 24349) | int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *ke...
function ecc_import_ex (line 24361) | int ecc_import_ex(const unsigned char *in, unsigned long inlen, ecc_key ...
function ecc_make_key (line 24475) | int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key) {
function ecc_make_key_ex (line 24490) | int ecc_make_key_ex(prng_state *prng, int wprng, ecc_key *key, const ltc...
function ecc_shared_secret (line 24619) | int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key,
function ecc_sign_hash (line 24722) | int ecc_sign_hash(const unsigned char *in, unsigned long inlen,
function ecc_sizes (line 24840) | void ecc_sizes(int *low, int *high) {
function ecc_test (line 24892) | int ecc_test(void) {
function ecc_verify_hash (line 25018) | int ecc_verify_hash(const unsigned char *sig, unsigned long siglen,
function hash_file (line 25292) | int hash_file(int hash, const char *fname, unsigned char *out, unsigned ...
function hash_filehandle (line 25350) | int hash_filehandle(int hash, FILE *in, unsigned char *out, unsigned lon...
function hash_memory (line 25422) | int hash_memory(int hash, const unsigned char *in, unsigned long inlen, ...
function hash_memory_multi (line 25493) | int hash_memory_multi(int hash, unsigned char *out, unsigned long *outlen,
function ltc_ecc_is_valid_idx (line 25583) | int ltc_ecc_is_valid_idx(int n) {
function ltc_ecc_map (line 25631) | int ltc_ecc_map(ecc_point *P, void *modulus, void *mp) {
function ltc_ecc_mul2add (line 25732) | int ltc_ecc_mul2add(ecc_point *A, void *kA,
function ltc_ecc_mulmod (line 25976) | int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, i...
function ltc_ecc_mulmod (line 26240) | int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, i...
function ecc_point (line 26434) | ecc_point *ltc_ecc_new_point(void) {
function ltc_ecc_del_point (line 26451) | void ltc_ecc_del_point(ecc_point *p) {
function ltc_ecc_projective_add_point (line 26498) | int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *...
function ltc_ecc_projective_dbl_point (line 26814) | int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *modul...
function mpi_to_ltc_error (line 27087) | static int mpi_to_ltc_error(int err) {
function init (line 27098) | static int init(void **a) {
function deinit (line 27113) | static void deinit(void *a) {
function neg (line 27119) | static int neg(void *a, void *b) {
function copy (line 27125) | static int copy(void *a, void *b) {
function init_copy (line 27131) | static int init_copy(void **a, void *b) {
function set_int (line 27139) | static int set_int(void *a, unsigned long b) {
function get_int (line 27144) | static unsigned long get_int(void *a) {
function get_digit (line 27149) | static unsigned long get_digit(void *a, int n) {
function get_digit_count (line 27157) | static int get_digit_count(void *a) {
function compare (line 27165) | static int compare(void *a, void *b) {
function compare_d (line 27184) | static int compare_d(void *a, unsigned long b) {
function count_bits (line 27202) | static int count_bits(void *a) {
function count_lsb_bits (line 27207) | static int count_lsb_bits(void *a) {
function twoexpt (line 27212) | static int twoexpt(void *a, int n) {
function read_radix (line 27220) | static int read_radix(void *a, const char *b, int radix) {
function write_radix (line 27227) | static int write_radix(void *a, char *b, int radix) {
function unsigned_size (line 27234) | static unsigned long unsigned_size(void *a) {
function unsigned_write (line 27240) | static int unsigned_write(void *a, unsigned char *b) {
function unsigned_read (line 27247) | static int unsigned_read(void *a, unsigned char *b, unsigned long len) {
function add (line 27254) | static int add(void *a, void *b, void *c) {
function addi (line 27261) | static int addi(void *a, unsigned long b, void *c) {
function sub (line 27268) | static int sub(void *a, void *b, void *c) {
function subi (line 27275) | static int subi(void *a, unsigned long b, void *c) {
function mul (line 27282) | static int mul(void *a, void *b, void *c) {
function muli (line 27289) | static int muli(void *a, unsigned long b, void *c) {
function sqr (line 27296) | static int sqr(void *a, void *b) {
function divide (line 27303) | static int divide(void *a, void *b, void *c, void *d) {
function div_2 (line 27309) | static int div_2(void *a, void *b) {
function modi (line 27316) | static int modi(void *a, unsigned long b, unsigned long *c) {
function gcd (line 27331) | static int gcd(void *a, void *b, void *c) {
function lcm (line 27339) | static int lcm(void *a, void *b, void *c) {
function mulmod (line 27346) | static int mulmod(void *a, void *b, void *c, void *d) {
function sqrmod (line 27354) | static int sqrmod(void *a, void *b, void *c) {
function invmod (line 27362) | static int invmod(void *a, void *b, void *c) {
function montgomery_setup (line 27370) | static int montgomery_setup(void *a, void **b) {
function montgomery_normalization (line 27386) | static int montgomery_normalization(void *a, void *b) {
function montgomery_reduce (line 27393) | static int montgomery_reduce(void *a, void *b, void *c) {
function montgomery_deinit (line 27401) | static void montgomery_deinit(void *a) {
function exptmod (line 27405) | static int exptmod(void *a, void *b, void *c, void *d) {
function isprime (line 27413) | static int isprime(void *a, int *b) {
function ltc_init_multi (line 27584) | int ltc_init_multi(void **a, ...) {
function ltc_deinit_multi (line 27611) | void ltc_deinit_multi(void *a, ...) {
function pkcs_1_i2osp (line 27659) | int pkcs_1_i2osp(void *n, unsigned long modulus_len, unsigned char *out) {
function pkcs_1_mgf1 (line 27708) | int pkcs_1_mgf1(int hash_idx,
function pkcs_1_oaep_decode (line 27820) | int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen,
function pkcs_1_oaep_encode (line 28010) | int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen,
function pkcs_1_os2ip (line 28175) | int pkcs_1_os2ip(void *n, unsigned char *in, unsigned long inlen) {
function pkcs_1_pss_decode (line 28217) | int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghas...
function pkcs_1_pss_encode (line 28417) | int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghas...
function pkcs_1_v1_5_decode (line 28591) | int pkcs_1_v1_5_decode(const unsigned char *msg,
function pkcs_1_v1_5_encode (line 28706) | int pkcs_1_v1_5_encode(const unsigned char *msg,
function rand_prime (line 28804) | int rand_prime(void *N, long len, prng_state *prng, int wprng) {
function rng_nix (line 28890) | static unsigned long rng_nix(unsigned char *buf, unsigned long len,
function rng_ansic (line 28929) | static unsigned long rng_ansic(unsigned char *buf, unsigned long len,
function rng_win32 (line 28972) | static unsigned long rng_win32(unsigned char *buf, unsigned long len,
function rng_alleged (line 28994) | static unsigned long rng_alleged(unsigned char *out, unsigned long outlen,
function rng_get_bytes (line 29006) | unsigned long rng_get_bytes(unsigned char *out, unsigned long outlen,
function rng_make_prng (line 29065) | int rng_make_prng(int bits, int wprng, prng_state *prng,
function rsa_decrypt_key_ex (line 29142) | int rsa_decrypt_key_ex(const unsigned char *in, unsigned long inlen,
function rsa_encrypt_key_ex (line 29248) | int rsa_encrypt_key_ex(const unsigned char *in, unsigned long inlen,
function rsa_exptmod (line 29345) | int rsa_exptmod(const unsigned char *in, unsigned long inlen,
function rsa_free (line 29472) | void rsa_free(rsa_key *key) {
function rsa_import (line 29509) | int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *ke...
function rsa_make_key (line 29658) | int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key ...
function rsa_sign_hash_ex (line 29813) | int rsa_sign_hash_ex(const unsigned char *in, unsigned long inlen,
function rsa_verify_hash_ex (line 29946) | int rsa_verify_hash_ex(const unsigned char *sig, unsigned long siglen,
type ltc_prng_descriptor (line 30110) | struct ltc_prng_descriptor
function sprng_start (line 30128) | int sprng_start(prng_state *prng) {
function sprng_add_entropy (line 30139) | int sprng_add_entropy(const unsigned char *in, unsigned long inlen, prng...
function sprng_ready (line 30148) | int sprng_ready(prng_state *prng) {
function sprng_read (line 30159) | unsigned long sprng_read(unsigned char *out, unsigned long outlen, prng_...
function sprng_done (line 30169) | int sprng_done(prng_state *prng) {
function sprng_export (line 30180) | int sprng_export(unsigned char *out, unsigned long *outlen, prng_state *...
function sprng_import (line 30194) | int sprng_import(const unsigned char *in, unsigned long inlen, prng_stat...
function sprng_test (line 30202) | int sprng_test(void) {
function zeromem (line 30236) | void zeromem(void *out, size_t outlen) {
type ltc_hash_descriptor (line 30270) | struct ltc_hash_descriptor
function sha1_compress (line 30296) | static int sha1_compress(hash_state *md, unsigned char *buf)
function sha1_compress (line 30423) | static int sha1_compress(hash_state *md, unsigned char *buf) {
function sha1_init (line 30437) | int sha1_init(hash_state *md) {
function sha1_done (line 30464) | int sha1_done(hash_state *md, unsigned char *out) {
function sha1_test (line 30515) | int sha1_test(void) {
type ltc_hash_descriptor (line 30576) | struct ltc_hash_descriptor
function sha256_compress (line 30627) | static int sha256_compress(hash_state * md, unsigned char *buf)
function sha256_compress (line 30753) | static int sha256_compress(hash_state * md, unsigned char *buf)
function sha256_init (line 30767) | int sha256_init(hash_state * md)
function sha256_done (line 30799) | int sha256_done(hash_state * md, unsigned char *out)
function sha256_test (line 30852) | int sha256_test(void)
type ltc_hash_descriptor (line 30919) | struct ltc_hash_descriptor
function sha384_init (line 30942) | int sha384_init(hash_state * md)
function sha384_done (line 30965) | int sha384_done(hash_state * md, unsigned char *out)
function sha384_test (line 30988) | int sha384_test(void)
type ltc_hash_descriptor (line 31057) | struct ltc_hash_descriptor
function sha512_compress (line 31140) | static int sha512_compress(hash_state * md, unsigned char *buf)
function sha512_compress (line 31210) | static int sha512_compress(hash_state * md, unsigned char *buf)
function sha512_init (line 31224) | int sha512_init(hash_state * md)
function sha512_done (line 31255) | int sha512_done(hash_state * md, unsigned char *out)
function sha512_test (line 31315) | int sha512_test(void)
function hmac_init (line 31401) | int hmac_init(hmac_state *hmac, int hash, const unsigned char *key, unsi...
function hmac_process (line 31510) | int hmac_process(hmac_state *hmac, const unsigned char *in, unsigned lon...
function hmac_done (line 31557) | int hmac_done(hmac_state *hmac, unsigned char *out, unsigned long *outlen)
type ltc_cipher_descriptor (line 32719) | struct ltc_cipher_descriptor
type ltc_cipher_descriptor (line 32728) | struct ltc_cipher_descriptor
type ltc_cipher_descriptor (line 32744) | struct ltc_cipher_descriptor
type ltc_cipher_descriptor (line 32753) | struct ltc_cipher_descriptor
function ulong32 (line 32767) | static ulong32 setup_mix(ulong32 temp)
function ulong32 (line 32777) | static ulong32 setup_mix2(ulong32 temp)
function SETUP (line 32795) | int SETUP(const unsigned char *key, int keylen, int num_rounds, symmetri...
function ECB_ENC (line 32961) | int ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *s...
function ECB_ENC (line 33120) | int ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *s...
function ECB_DEC (line 33140) | int ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *s...
function ECB_DEC (line 33300) | int ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *s...
function ECB_TEST (line 33312) | int ECB_TEST(void)
function ECB_DONE (line 33399) | void ECB_DONE(symmetric_key *skey)
function ECB_KS (line 33410) | int ECB_KS(int *keysize)
function cbc_decrypt (line 33464) | int cbc_decrypt(const unsigned char *ct, unsigned char *pt, unsigned lon...
function cbc_done (line 33558) | int cbc_done(symmetric_CBC *cbc)
function cbc_encrypt (line 33607) | int cbc_encrypt(const unsigned char *pt, unsigned char *ct, unsigned lon...
function cbc_getiv (line 33705) | int cbc_getiv(unsigned char *IV, unsigned long *len, symmetric_CBC *cbc)
function cbc_setiv (line 33754) | int cbc_setiv(const unsigned char *IV, unsigned long len, symmetric_CBC ...
function cbc_start (line 33802) | int cbc_start(int cipher, const unsigned char *IV, const unsigned char *...
function gcm_add_iv (line 33863) | int gcm_add_iv(gcm_state *gcm,
function gcm_done (line 33959) | int gcm_done(gcm_state *gcm,
function gcm_init (line 34050) | int gcm_init(gcm_state *gcm, int cipher,
function gcm_process (line 34160) | int gcm_process(gcm_state *gcm,
function gcm_mult_h (line 34314) | void gcm_mult_h(gcm_state *gcm, unsigned char *I)
function gcm_rightshift (line 34413) | static void gcm_rightshift(unsigned char *a)
function gcm_gf_mult (line 34433) | void gcm_gf_mult(const unsigned char *a, const unsigned char *b, unsigne...
function gcm_gf_mult (line 34467) | void gcm_gf_mult(const unsigned char *a, const unsigned char *b, unsigne...
function gcm_add_aad (line 34600) | int gcm_add_aad(gcm_state *gcm,
function gcm_reset (line 34724) | int gcm_reset(gcm_state *gcm)
type ltc_hash_descriptor (line 34765) | struct ltc_hash_descriptor
function md5_compress (line 34847) | static int md5_compress(hash_state *md, unsigned char *buf)
function md5_compress (line 34963) | static int md5_compress(hash_state *md, unsigned char *buf)
function md5_init (line 34977) | int md5_init(hash_state * md)
function md5_done (line 35004) | int md5_done(hash_state * md, unsigned char *out)
function md5_test (line 35057) | int md5_test(void)
function ctr_encrypt (line 35139) | int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned lon...
function ctr_done (line 35246) | int ctr_done(symmetric_CTR *ctr)
function ctr_decrypt (line 35292) | int ctr_decrypt(const unsigned char *ct, unsigned char *pt, unsigned lon...
function ctr_start (line 35338) | int ctr_start( int cipher,
function ctr_setiv (line 35434) | int ctr_setiv(const unsigned char *IV, unsigned long len, symmetric_CTR ...
function ctr_getiv (line 35490) | int ctr_getiv(unsigned char *IV, unsigned long *len, symmetric_CTR *ctr)
function fsum (line 35591) | static void fsum(int64_t *output, const int64_t *in) {
function fdifference (line 35602) | static void fdifference(int64_t *output, const int64_t *in) {
function fscalar_product (line 35610) | static void fscalar_product(int64_t *output, const int64_t *in, const in...
function fproduct (line 35622) | static void fproduct(int64_t *output, const int64_t *in2, const int64_t ...
function freduce_degree (line 35726) | static void freduce_degree(int64_t *output) {
function div_by_2_26 (line 35759) | static inline int64_t div_by_2_26(const int64_t v) {
function div_by_2_25 (line 35771) | static inline int64_t div_by_2_25(const int64_t v) {
function div_s32_by_2_25 (line 35782) | static inline int32_t div_s32_by_2_25(const int32_t v) {
function freduce_coefficients (line 35791) | static void freduce_coefficients(int64_t *output) {
function fmul (line 35839) | static void fmul(int64_t *output, const int64_t *in, const int64_t *in2) {
function fsquare_inner (line 35847) | static void fsquare_inner(int64_t *output, const int64_t *in) {
function fsquare (line 35905) | static void fsquare(int64_t *output, const int64_t *in) {
function fexpand (line 35914) | static void fexpand(int64_t *output, const uint8_t *input) {
function fcontract (line 35930) | static void fcontract(uint8_t *output, int64_t *input) {
function fmonty (line 36010) | static void fmonty(int64_t *x2, int64_t *z2, /* output 2Q */
function swap_conditional (line 36069) | static void swap_conditional(int64_t a[19], int64_t b[19], int64_t iswap) {
function cmult (line 36086) | static void cmult(int64_t *resultx, int64_t *resultz, const uint8_t *n, ...
function crecip (line 36135) | static void crecip(int64_t *out, const int64_t *z) {
function curve25519 (line 36203) | void curve25519(uint8_t *mypublic, const uint8_t *secret, const uint8_t ...
type chacha_ctx (line 36382) | struct chacha_ctx {
type chacha_ctx (line 36388) | struct chacha_ctx
type chacha_ctx (line 36389) | struct chacha_ctx
type chacha_ctx (line 36390) | struct chacha_ctx
type chacha_ctx (line 36391) | struct chacha_ctx
type u8 (line 36402) | typedef unsigned char u8;
type u32 (line 36403) | typedef unsigned int u32;
type chacha_ctx (line 36405) | typedef struct chacha_ctx chacha_ctx;
function chacha_keysetup (line 36453) | static inline void chacha_keysetup(chacha_ctx *x, const u8 *k, u32 kbits) {
function chacha_key (line 36490) | static inline void chacha_key(chacha_ctx *x, u8 *k) {
function chacha_nonce (line 36502) | static inline void chacha_nonce(chacha_ctx *x, u8 *nonce) {
function chacha_ivsetup (line 36508) | static inline void chacha_ivsetup(chacha_ctx *x, const u8 *iv, const u8 ...
function chacha_ivsetup_96bitnonce (line 36523) | static inline void chacha_ivsetup_96bitnonce(chacha_ctx *x, const u8 *iv...
function chacha_ivupdate (line 36536) | static inline void chacha_ivupdate(chacha_ctx *x, const u8 *iv, const u8...
function chacha_encrypt_bytes (line 36547) | static inline void chacha_encrypt_bytes(chacha_ctx *x, const u8 *m, u8 *...
function chacha20_block (line 36705) | static inline void chacha20_block(chacha_ctx *x, unsigned char *c, u_int...
function poly1305_generate_key (line 36730) | static inline int poly1305_generate_key(unsigned char *key256, unsigned ...
type poly1305_state_internal_t (line 36751) | typedef struct poly1305_state_internal_t {
function _private_tls_U8TO32 (line 36761) | static unsigned long _private_tls_U8TO32(const unsigned char *p) {
function _private_tls_U32TO8 (line 36770) | static void _private_tls_U32TO8(unsigned char *p, unsigned long v) {
function _private_tls_poly1305_init (line 36777) | void _private_tls_poly1305_init(poly1305_context *ctx, const unsigned ch...
function _private_tls_poly1305_blocks (line 36804) | static void _private_tls_poly1305_blocks(poly1305_state_internal_t *st, ...
function _private_tls_poly1305_finish (line 36869) | void _private_tls_poly1305_finish(poly1305_context *ctx, unsigned char m...
function _private_tls_poly1305_update (line 36955) | void _private_tls_poly1305_update(poly1305_context *ctx, const unsigned ...
function poly1305_verify (line 36990) | int poly1305_verify(const unsigned char mac1[16], const unsigned char ma...
function chacha20_poly1305_key (line 36999) | void chacha20_poly1305_key(struct chacha_ctx *ctx, unsigned char *poly13...
function chacha20_poly1305_aead (line 37010) | int chacha20_poly1305_aead(struct chacha_ctx *ctx, unsigned char *pt, u...
type KeyExchangeAlgorithm (line 37045) | typedef enum {
type TLSClientCertificateType (line 37055) | typedef enum {
type TLSHashAlgorithm (line 37068) | typedef enum {
type TLSSignatureAlgorithm (line 37079) | typedef enum {
type _private_OID_chain (line 37087) | struct _private_OID_chain {
type TLSCertificate (line 37092) | struct TLSCertificate {
type TLSCipher (line 37129) | typedef struct {
type TLSHash (line 37167) | typedef struct {
type DHKey (line 37196) | typedef struct {
type ECCCurveParameters (line 37246) | struct ECCCurveParameters {
type ECCCurveParameters (line 37259) | struct ECCCurveParameters
type ECCCurveParameters (line 37272) | struct ECCCurveParameters
type ECCCurveParameters (line 37284) | struct ECCCurveParameters
type ECCCurveParameters (line 37296) | struct ECCCurveParameters
type ECCCurveParameters (line 37308) | struct ECCCurveParameters
type ECCCurveParameters (line 37320) | struct ECCCurveParameters
type ECCCurveParameters (line 37332) | struct ECCCurveParameters
type ECCCurveParameters (line 37346) | struct ECCCurveParameters
type ECCCurveParameters (line 37359) | struct ECCCurveParameters
function init_curve (line 37361) | void init_curve(struct ECCCurveParameters *curve) {
function init_curves (line 37371) | void init_curves() {
type TLSContext (line 37382) | struct TLSContext {
type TLSPacket (line 37469) | struct TLSPacket {
type TLSCertificate (line 37537) | struct TLSCertificate
type TLSContext (line 37537) | struct TLSContext
type TLSContext (line 37538) | struct TLSContext
type TLSPacket (line 37539) | struct TLSPacket
type TLSContext (line 37539) | struct TLSContext
type TLSContext (line 37540) | struct TLSContext
type TLSPacket (line 37542) | struct TLSPacket
type TLSPacket (line 37543) | struct TLSPacket
type TLSContext (line 37543) | struct TLSContext
type TLSPacket (line 37544) | struct TLSPacket
type TLSContext (line 37544) | struct TLSContext
type TLSPacket (line 37545) | struct TLSPacket
type TLSContext (line 37545) | struct TLSContext
type TLSPacket (line 37546) | struct TLSPacket
type TLSContext (line 37546) | struct TLSContext
type TLSPacket (line 37547) | struct TLSPacket
type TLSContext (line 37547) | struct TLSContext
type TLSPacket (line 37548) | struct TLSPacket
type TLSContext (line 37548) | struct TLSContext
type TLSContext (line 37549) | struct TLSContext
type TLSContext (line 37550) | struct TLSContext
type TLSContext (line 37551) | struct TLSContext
type TLSContext (line 37552) | struct TLSContext
type TLSPacket (line 37553) | struct TLSPacket
type TLSContext (line 37554) | struct TLSContext
type TLSContext (line 37555) | struct TLSContext
type TLSPacket (line 37555) | struct TLSPacket
type TLSContext (line 37557) | struct TLSContext
type TLSContext (line 37558) | struct TLSContext
type TLSPacket (line 37563) | struct TLSPacket
type TLSContext (line 37563) | struct TLSContext
type TLSPacket (line 37564) | struct TLSPacket
type TLSContext (line 37564) | struct TLSContext
function _private_b64_decodeblock (line 37577) | void _private_b64_decodeblock(unsigned char in[4], unsigned char out[3]) {
function _private_b64_decode (line 37583) | int _private_b64_decode(const char *in_buffer, int in_buffer_size, unsig...
function dtls_reset_cookie_secret (line 37619) | void dtls_reset_cookie_secret() {
function tls_init (line 37623) | void tls_init() {
function _private_tls_dh_shared_secret (line 37653) | int _private_tls_dh_shared_secret(DHKey *private_key, DHKey *public_key,...
type TLSContext (line 37686) | struct TLSContext
type TLSContext (line 37736) | struct TLSContext
type ECCCurveParameters (line 37742) | struct ECCCurveParameters
type TLSContext (line 37781) | struct TLSContext
type TLSContext (line 37816) | struct TLSContext
function _private_rsa_verify_hash_md5sha1 (line 37851) | int _private_rsa_verify_hash_md5sha1(const unsigned char *sig, unsigned ...
function _private_tls_verify_rsa (line 37905) | int _private_tls_verify_rsa(struct TLSContext *context, unsigned int has...
function _private_rsa_sign_hash_md5sha1 (line 38034) | int _private_rsa_sign_hash_md5sha1(const unsigned char *in, unsigned lon...
function _private_tls_sign_rsa (line 38057) | int _private_tls_sign_rsa(struct TLSContext *context, unsigned int hash_...
function _private_tls_is_point (line 38181) | static int _private_tls_is_point(ecc_key *key) {
function _private_tls_ecc_import_key (line 38254) | int _private_tls_ecc_import_key(const unsigned char *private_key, int pr...
function _private_tls_sign_ecdsa (line 38304) | int _private_tls_sign_ecdsa(struct TLSContext *context, unsigned int has...
function _private_tls_ecc_import_pk (line 38445) | int _private_tls_ecc_import_pk(const unsigned char *public_key, int publ...
function _private_tls_verify_ecdsa (line 38491) | int _private_tls_verify_ecdsa(struct TLSContext *context, unsigned int h...
function _private_tls_random_int (line 38615) | unsigned int _private_tls_random_int(int limit) {
function _private_tls_sleep (line 38624) | void _private_tls_sleep(unsigned int microseconds) {
function _private_random_sleep (line 38641) | void _private_random_sleep(struct TLSContext *context, int max_microseco...
function _private_tls_prf_helper (line 38648) | void _private_tls_prf_helper(int hash_idx, unsigned long dlen, unsigned ...
function _private_tls_hkdf_label (line 38693) | int _private_tls_hkdf_label(const char *label, unsigned char label_len, ...
function _private_tls_hkdf_extract (line 38712) | int _private_tls_hkdf_extract(unsigned int mac_length, unsigned char *ou...
function _private_tls_hkdf_expand (line 38735) | void _private_tls_hkdf_expand(unsigned int mac_length, unsigned char *ou...
function _private_tls_hkdf_expand_label (line 38773) | void _private_tls_hkdf_expand_label(unsigned int mac_length, unsigned ch...
function _private_tls_prf (line 38782) | void _private_tls_prf(struct TLSContext *context,
function _private_tls_key_length (line 38850) | int _private_tls_key_length(struct TLSContext *context) {
function _private_tls_is_aead (line 38887) | int _private_tls_is_aead(struct TLSContext *context) {
function _private_tls_mac_length (line 38911) | unsigned int _private_tls_mac_length(struct TLSContext *context) {
function _private_tls13_key (line 38956) | int _private_tls13_key(struct TLSContext *context, int handshake) {
function _private_tls_expand_key (line 39158) | int _private_tls_expand_key(struct TLSContext *context) {
function _private_tls_compute_key (line 39284) | int _private_tls_compute_key(struct TLSContext *context, unsigned int ke...
function _is_oid (line 39388) | int _is_oid(const unsigned char *oid, const unsigned char *compare_to, i...
function _is_oid2 (line 39399) | int _is_oid2(const unsigned char *oid, const unsigned char *compare_to, ...
type TLSCertificate (line 39412) | struct TLSCertificate
type TLSCertificate (line 39413) | struct TLSCertificate
type TLSCertificate (line 39413) | struct TLSCertificate
type TLSCertificate (line 39413) | struct TLSCertificate
type TLSCertificate (line 39415) | struct TLSCertificate
function tls_certificate_valid_subject_name (line 39419) | int tls_certificate_valid_subject_name(const unsigned char *cert_subject...
function tls_certificate_valid_subject (line 39472) | int tls_certificate_valid_subject(struct TLSCertificate *cert, const cha...
function tls_certificate_is_valid (line 39488) | int tls_certificate_is_valid(struct TLSCertificate *cert) {
function tls_certificate_set_copy (line 39520) | void tls_certificate_set_copy(unsigned char **member, const unsigned cha...
function tls_certificate_set_copy_date (line 39534) | void tls_certificate_set_copy_date(unsigned char **member, const unsigne...
function tls_certificate_set_key (line 39555) | void tls_certificate_set_key(struct TLSCertificate *cert, const unsigned...
function tls_certificate_set_priv (line 39565) | void tls_certificate_set_priv(struct TLSCertificate *cert, const unsigne...
function tls_certificate_set_sign_key (line 39571) | void tls_certificate_set_sign_key(struct TLSCertificate *cert, const uns...
type TLSCertificate (line 39583) | struct TLSCertificate
function tls_certificate_set_exponent (line 39723) | void tls_certificate_set_exponent(struct TLSCertificate *cert, const uns...
function tls_certificate_set_serial (line 39729) | void tls_certificate_set_serial(struct TLSCertificate *cert, const unsig...
function tls_certificate_set_algorithm (line 39735) | void tls_certificate_set_algorithm(struct TLSContext *context, unsigned ...
function tls_destroy_certificate (line 39829) | void tls_destroy_certificate(struct TLSCertificate *cert) {
type TLSPacket (line 39861) | struct TLSPacket
type TLSContext (line 39861) | struct TLSContext
type TLSPacket (line 39862) | struct TLSPacket
type TLSPacket (line 39862) | struct TLSPacket
type TLSPacket (line 39862) | struct TLSPacket
function tls_destroy_packet (line 39922) | void tls_destroy_packet(struct TLSPacket *packet) {
function _private_tls_crypto_create (line 39930) | int _private_tls_crypto_create(struct TLSContext *context, int key_lengt...
function _private_tls_crypto_encrypt (line 39987) | int _private_tls_crypto_encrypt(struct TLSContext *context, unsigned cha...
function _private_tls_crypto_decrypt (line 39995) | int _private_tls_crypto_decrypt(struct TLSContext *context, unsigned cha...
function _private_tls_crypto_done (line 40003) | void _private_tls_crypto_done(struct TLSContext *context) {
type TLSPacket (line 40019) | struct TLSPacket
function tls_packet_append (line 40316) | int tls_packet_append(struct TLSPacket *packet, const unsigned char *buf...
function tls_packet_uint8 (line 40342) | int tls_packet_uint8(struct TLSPacket *packet, unsigned char i) {
function tls_packet_uint16 (line 40346) | int tls_packet_uint16(struct TLSPacket *packet, unsigned short i) {
function tls_packet_uint32 (line 40351) | int tls_packet_uint32(struct TLSPacket *packet, unsigned int i) {
function tls_packet_uint24 (line 40356) | int tls_packet_uint24(struct TLSPacket *packet, unsigned int i) {
function tls_random (line 40367) | int tls_random(unsigned char *key, int len) {
function TLSHash (line 40407) | TLSHash *_private_tls_ensure_hash(struct TLSContext *context) {
function _private_tls_destroy_hash (line 40418) | void _private_tls_destroy_hash(struct TLSContext *context) {
function _private_tls_create_hash (line 40425) | void _private_tls_create_hash(struct TLSContext *context) {
function _private_tls_update_hash (line 40457) | int _private_tls_update_hash(struct TLSContext *context, const unsigned ...
function _private_tls_change_hash_type (line 40507) | int _private_tls_change_hash_type(struct TLSContext *context) {
function _private_tls_done_hash (line 40527) | int _private_tls_done_hash(struct TLSContext *context, unsigned char *ho...
function _private_tls_get_hash_idx (line 40574) | int _private_tls_get_hash_idx(struct TLSContext *context) {
function _private_tls_get_hash (line 40588) | int _private_tls_get_hash(struct TLSContext *context, unsigned char *hou...
function _private_tls_write_packet (line 40631) | int _private_tls_write_packet(struct TLSPacket *packet) {
function _private_tls_write_app_data (line 40663) | int _private_tls_write_app_data(struct TLSContext *context, const unsign...
type TLSContext (line 40682) | struct TLSContext
type TLSContext (line 40701) | struct TLSContext
function tls_buffer_clear (line 40750) | void tls_buffer_clear(struct TLSContext *context) {
function tls_established (line 40758) | int tls_established(struct TLSContext *context) {
function tls_read_clear (line 40775) | void tls_read_clear(struct TLSContext *context) {
function tls_read (line 40783) | int tls_read(struct TLSContext *context, unsigned char *buf, unsigned in...
type TLSContext (line 40804) | struct TLSContext
type TLSContext (line 40805) | struct TLSContext
type TLSContext (line 40805) | struct TLSContext
type TLSContext (line 40805) | struct TLSContext
type TLSContext (line 40807) | struct TLSContext
type ECCCurveParameters (line 40817) | struct ECCCurveParameters
type TLSContext (line 40817) | struct TLSContext
type ECCCurveParameters (line 40817) | struct ECCCurveParameters
type ECCCurveParameters (line 40818) | struct ECCCurveParameters
type TLSContext (line 40828) | struct TLSContext
type TLSContext (line 40828) | struct TLSContext
type TLSContext (line 40829) | struct TLSContext
type TLSContext (line 40833) | struct TLSContext
type TLSContext (line 40833) | struct TLSContext
type TLSContext (line 40835) | struct TLSContext
function _private_tls_dhe_free (line 40861) | void _private_tls_dhe_free(struct TLSContext *context) {
function _private_tls_dhe_create (line 40869) | void _private_tls_dhe_create(struct TLSContext *context) {
function _private_tls_ecc_dhe_free (line 40876) | void _private_tls_ecc_dhe_free(struct TLSContext *context) {
function _private_tls_ecc_dhe_create (line 40884) | void _private_tls_ecc_dhe_create(struct TLSContext *context) {
function tls_set_default_dhe_pg (line 40890) | int tls_set_default_dhe_pg(struct TLSContext *context, const char *p_hex...
type TLSContext (line 40922) | struct TLSContext
function tls_add_alpn (line 40928) | int tls_add_alpn(struct TLSContext *context, const char *alpn) {
function tls_alpn_contains (line 40953) | int tls_alpn_contains(struct TLSContext *context, const char *alpn, unsi...
function tls_destroy_context (line 40976) | void tls_destroy_context(struct TLSContext *context) {
function _private_tls_reset_context (line 41051) | void _private_tls_reset_context(struct TLSContext *context) {
function tls_cipher_supported (line 41116) | int tls_cipher_supported(struct TLSContext *context, unsigned short ciph...
function tls_cipher_is_fs (line 41189) | int tls_cipher_is_fs(struct TLSContext *context, unsigned short cipher) {
function _private_tls_prefer_ktls (line 41247) | int _private_tls_prefer_ktls(struct TLSContext *context, unsigned short ...
function tls_choose_cipher (line 41266) | int tls_choose_cipher(struct TLSContext *context, const unsigned char *b...
function tls_cipher_is_ephemeral (line 41311) | int tls_cipher_is_ephemeral(struct TLSContext *context) {
type TLSContext (line 41351) | struct TLSContext
function _private_tls_dh_export_Y (line 41422) | int _private_tls_dh_export_Y(unsigned char *Ybuf, unsigned long *Ylen, D...
function _private_tls_dh_export_pqY (line 41436) | int _private_tls_dh_export_pqY(unsigned char *pbuf, unsigned long *plen,...
function _private_tls_dh_clear_key (line 41473) | void _private_tls_dh_clear_key(DHKey *key) {
function _private_tls_dh_make_key (line 41481) | int _private_tls_dh_make_key(int keysize, DHKey *key, const char *pbuf, ...
function tls_is_ecdsa (line 41559) | int tls_is_ecdsa(struct TLSContext *context) {
type TLSPacket (line 41581) | struct TLSPacket
type TLSContext (line 41581) | struct TLSContext
type TLSPacket (line 41583) | struct TLSPacket
function else (line 41636) | else
function _private_dtls_handshake_data (line 41658) | void _private_dtls_handshake_data(struct TLSContext *context, struct TLS...
function _private_dtls_handshake_copyframesize (line 41667) | void _private_dtls_handshake_copyframesize(struct TLSPacket *packet) {
type TLSPacket (line 41673) | struct TLSPacket
type TLSContext (line 41673) | struct TLSContext
type TLSPacket (line 41676) | struct TLSPacket
function _private_tls_set_session_id (line 41853) | void _private_tls_set_session_id(struct TLSContext *context) {
type TLSPacket (line 41862) | struct TLSPacket
type TLSContext (line 41862) | struct TLSContext
type TLSPacket (line 41865) | struct TLSPacket
type TLSPacket (line 42441) | struct TLSPacket
type TLSContext (line 42441) | struct TLSContext
type TLSPacket (line 42443) | struct TLSPacket
function _private_dtls_build_cookie (line 42532) | int _private_dtls_build_cookie(struct TLSContext *context) {
type TLSPacket (line 42558) | struct TLSPacket
type TLSContext (line 42558) | struct TLSContext
type TLSPacket (line 42560) | struct TLSPacket
function _private_dtls_check_packet (line 42592) | int _private_dtls_check_packet(const unsigned char *buf, int buf_len) {
function _private_dtls_reset (line 42608) | void _private_dtls_reset(struct TLSContext *context) {
function tls_parse_verify_request (line 42616) | int tls_parse_verify_request(struct TLSContext *context, const unsigned ...
function _private_dtls_reset_cookie (line 42653) | void _private_dtls_reset_cookie(struct TLSContext *context) {
function _private_tls_parse_key_share (line 42660) | int _private_tls_parse_key_share(struct TLSContext *context, const unsig...
function tls_parse_hello (line 42878) | int tls_parse_hello(struct TLSContext *context, const unsigned char *buf...
function tls_parse_certificate (line 43307) | int tls_parse_certificate(struct TLSContext *context, const unsigned cha...
function _private_tls_parse_dh (line 43423) | int _private_tls_parse_dh(const unsigned char *buf, int buf_len, const u...
function _private_tls_parse_random (line 43440) | int _private_tls_parse_random(struct TLSContext *context, const unsigned...
function _private_tls_build_random (line 43485) | int _private_tls_build_random(struct TLSPacket *packet) {
type TLSContext (line 43531) | struct TLSContext
function tls_parse_server_key_exchange (line 43565) | int tls_parse_server_key_exchange(struct TLSContext *context, const unsi...
function tls_parse_client_key_exchange (line 43820) | int tls_parse_client_key_exchange(struct TLSContext *context, const unsi...
function tls_parse_server_hello_done (line 43858) | int tls_parse_server_hello_done(struct TLSContext *context, const unsign...
function tls_parse_finished (line 43878) | int tls_parse_finished(struct TLSContext *context, const unsigned char *...
function tls_parse_verify_tls13 (line 43997) | int tls_parse_verify_tls13(struct TLSContext *context, const unsigned ch...
function tls_parse_verify (line 44061) | int tls_parse_verify(struct TLSContext *context, const unsigned char *bu...
function tls_parse_payload (line 44109) | int tls_parse_payload(struct TLSContext *context, const unsigned char *b...
function _private_tls_hmac_message (line 44491) | unsigned int _private_tls_hmac_message(unsigned char local, struct TLSCo...
type TLSContext (line 44533) | struct TLSContext
function asn1_get_len (line 45014) | unsigned int asn1_get_len(const unsigned char *buffer, int buf_len, unsi...
function print_index (line 45048) | void print_index(const unsigned int *fields) {
function _is_field (line 45062) | int _is_field(const unsigned int *fields, const unsigned int *prefix) {
function _private_tls_hash_len (line 45072) | int _private_tls_hash_len(int algorithm) {
function tls_certificate_verify_signature (line 45169) | int tls_certificate_verify_signature(struct TLSCertificate *cert, struct...
function tls_certificate_chain_is_valid (line 45258) | int tls_certificate_chain_is_valid(struct TLSCertificate **certificates,...
function tls_certificate_chain_is_valid_root (line 45280) | int tls_certificate_chain_is_valid_root(struct TLSContext *context, stru...
function _private_is_oid (line 45299) | int _private_is_oid(struct _private_OID_chain *ref_chain, const unsigned...
function _private_asn1_parse (line 45310) | int _private_asn1_parse(struct TLSContext *context, struct TLSCertificat...
type TLSCertificate (line 45643) | struct TLSCertificate
type TLSContext (line 45643) | struct TLSContext
type TLSCertificate (line 45645) | struct TLSCertificate
function tls_load_certificates (line 45662) | int tls_load_certificates(struct TLSContext *context, const unsigned cha...
function tls_load_private_key (line 45712) | int tls_load_private_key(struct TLSContext *context, const unsigned char...
function tls_clear_certificates (line 45757) | int tls_clear_certificates(struct TLSContext *context) {
type TLSPacket (line 45783) | struct TLSPacket
type TLSContext (line 45783) | struct TLSContext
type TLSPacket (line 45793) | struct TLSPacket
type TLSPacket (line 45868) | struct TLSPacket
type TLSContext (line 45868) | struct TLSContext
type TLSCertificate (line 45873) | struct TLSCertificate
type TLSPacket (line 45874) | struct TLSPacket
type TLSCertificate (line 45892) | struct TLSCertificate
type TLSCertificate (line 45898) | struct TLSCertificate
type TLSCertificate (line 45905) | struct TLSCertificate
type TLSCertificate (line 45930) | struct TLSCertificate
type TLSPacket (line 45967) | struct TLSPacket
type TLSContext (line 45967) | struct TLSContext
type TLSPacket (line 45968) | struct TLSPacket
type TLSPacket (line 45991) | struct TLSPacket
type TLSContext (line 45991) | struct TLSContext
type TLSPacket (line 46000) | struct TLSPacket
type TLSPacket (line 46095) | struct TLSPacket
type TLSContext (line 46095) | struct TLSContext
type TLSPacket (line 46096) | struct TLSPacket
type TLSPacket (line 46103) | struct TLSPacket
type TLSContext (line 46103) | struct TLSContext
type TLSPacket (line 46104) | struct TLSPacket
type TLSPacket (line 46115) | struct TLSPacket
type TLSContext (line 46115) | struct TLSContext
type TLSPacket (line 46116) | struct TLSPacket
function tls_client_connect (line 46126) | int tls_client_connect(struct TLSContext *context) {
function tls_write (line 46133) | int tls_write(struct TLSContext *context, const unsigned char *data, uns...
type TLSPacket (line 46153) | struct TLSPacket
type TLSContext (line 46153) | struct TLSContext
type TLSPacket (line 46154) | struct TLSPacket
function _private_tls_read_from_file (line 46163) | int _private_tls_read_from_file(const char *fname, void *buf, int max_le...
function tls_consume_stream (line 46173) | int tls_consume_stream(struct TLSContext *context, const unsigned char *...
function tls_close_notify (line 46261) | void tls_close_notify(struct TLSContext *context) {
function tls_alert (line 46269) | void tls_alert(struct TLSContext *context, unsigned char critical, int c...
function tls_pending (line 46278) | int tls_pending(struct TLSContext *context) {
function tls_make_exportable (line 46284) | void tls_make_exportable(struct TLSContext *context, unsigned char expor...
type TLSContext (line 46296) | struct TLSContext
type TLSPacket (line 46297) | struct TLSPacket
function else (line 46333) | else
type TLSContext (line 46419) | struct TLSContext
type TLSContext (line 46420) | struct TLSContext
function tls_is_broken (line 46630) | int tls_is_broken(struct TLSContext *context) {
function tls_request_client_certificate (line 46636) | int tls_request_client_certificate(struct TLSContext *context) {
function tls_client_verified (line 46644) | int tls_client_verified(struct TLSContext *context) {
type TLSContext (line 46651) | struct TLSContext
function tls_sni_set (line 46657) | int tls_sni_set(struct TLSContext *context, const char *sni) {
function tls_load_root_certificates (line 46676) | int tls_load_root_certificates(struct TLSContext *context, const unsigne...
function tls_default_verify (line 46720) | int tls_default_verify(struct TLSContext *context, struct TLSCertificate...
function tls_unmake_ktls (line 46756) | int tls_unmake_ktls(struct TLSContext *context, int socket) {
function tls_make_ktls (line 46781) | int tls_make_ktls(struct TLSContext *context, int socket) {
function tls_print_certificate (line 46867) | void tls_print_certificate(const char *fname) {
function tls_remote_error (line 46900) | int tls_remote_error(struct TLSContext *context) {
function SSL_library_init (line 46909) | int SSL_library_init() {
function SSL_load_error_strings (line 46914) | void SSL_load_error_strings() {
function OpenSSL_add_all_algorithms (line 46918) | void OpenSSL_add_all_algorithms() {
function OpenSSL_add_all_ciphers (line 46922) | void OpenSSL_add_all_ciphers() {
function OpenSSL_add_all_digests (line 46926) | void OpenSSL_add_all_digests() {
function EVP_cleanup (line 46930) | void EVP_cleanup() {
function _tls_ssl_private_send_pending (line 46934) | int _tls_ssl_private_send_pending(int client_sock, struct TLSContext *co...
type TLSContext (line 46979) | struct TLSContext
type TLSContext (line 46979) | struct TLSContext
function SSLv3_server_method (line 46983) | int SSLv3_server_method() {
function SSLv3_client_method (line 46987) | int SSLv3_client_method() {
function SSL_CTX_use_certificate_file (line 46991) | int SSL_CTX_use_certificate_file(struct TLSContext *context, const char ...
function SSL_CTX_use_PrivateKey_file (line 47000) | int SSL_CTX_use_PrivateKey_file(struct TLSContext *context, const char *...
function SSL_CTX_check_private_key (line 47009) | int SSL_CTX_check_private_key(struct TLSContext *context) {
type TLSContext (line 47019) | struct TLSContext
function SSL_free (line 47027) | void SSL_free(struct TLSContext *context) {
function SSL_CTX_free (line 47034) | void SSL_CTX_free(struct TLSContext *context) {
function SSL_get_error (line 47038) | int SSL_get_error(struct TLSContext *context, int ret) {
function SSL_set_fd (line 47044) | int SSL_set_fd(struct TLSContext *context, int socket) {
type TLSContext (line 47061) | struct TLSContext
type TLSContext (line 47080) | struct TLSContext
function SSL_CTX_root_ca (line 47092) | int SSL_CTX_root_ca(struct TLSContext *context, const char *pem_filename) {
function SSL_CTX_set_verify (line 47135) | void SSL_CTX_set_verify(struct TLSContext *context, int mode, tls_valida...
function _private_tls_safe_read (line 47154) | int _private_tls_safe_read(struct TLSContext *context, void *buffer, int...
function SSL_accept (line 47167) | int SSL_accept(struct TLSContext *context) {
function SSL_connect (line 47194) | int SSL_connect(struct TLSContext *context) {
function SSL_shutdown (line 47226) | int SSL_shutdown(struct TLSContext *context) {
function SSL_write (line 47239) | int SSL_write(struct TLSContext *context, const void *buf, unsigned int ...
function SSL_read (line 47258) | int SSL_read(struct TLSContext *context, void *buf, unsigned int len) {
function SSL_pending (line 47289) | int SSL_pending(struct TLSContext *context) {
function SSL_set_io (line 47295) | int SSL_set_io(struct TLSContext *context, void *recv_cb, void *send_cb) {
type SRTPContext (line 47317) | struct SRTPContext {
type SRTPContext (line 47329) | struct SRTPContext
type SRTPContext (line 47330) | struct SRTPContext
type SRTPContext (line 47349) | struct SRTPContext
type SRTPContext (line 47349) | struct SRTPContext
type SRTPContext (line 47351) | struct SRTPContext
function _private_tls_srtp_key_derive (line 47358) | static int _private_tls_srtp_key_derive(const void *key, int keylen, con...
function srtp_key (line 47381) | int srtp_key(struct SRTPContext *context, const void *key, int keylen, c...
function srtp_inline (line 47417) | int srtp_inline(struct SRTPContext *context, const char *b64, int tag_bi...
function srtp_encrypt (line 47440) | int srtp_encrypt(struct SRTPContext *context, const unsigned char *pt_he...
function srtp_decrypt (line 47506) | int srtp_decrypt(struct SRTPContext *context, const unsigned char *pt_he...
function srtp_destroy (line 47566) | void srtp_destroy(struct SRTPContext *context) {
FILE: cryanc.h
type TLSAlertDescription (line 159) | typedef enum {
type TLSPacket (line 190) | struct TLSPacket
type TLSCertificate (line 191) | struct TLSCertificate
type TLSContext (line 192) | struct TLSContext
type ECCCurveParameters (line 193) | struct ECCCurveParameters
type TLS (line 194) | typedef struct TLSContext TLS;
type Certificate (line 195) | typedef struct TLSCertificate Certificate;
type TLSContext (line 197) | struct TLSContext
type TLSCertificate (line 197) | struct TLSCertificate
type TLSCertificate (line 207) | struct TLSCertificate
type TLSCertificate (line 208) | struct TLSCertificate
type TLSCertificate (line 210) | struct TLSCertificate
type TLSCertificate (line 213) | struct TLSCertificate
type TLSCertificate (line 214) | struct TLSCertificate
type TLSCertificate (line 215) | struct TLSCertificate
type TLSCertificate (line 216) | struct TLSCertificate
type TLSCertificate (line 217) | struct TLSCertificate
type TLSCertificate (line 218) | struct TLSCertificate
type TLSContext (line 219) | struct TLSContext
type TLSCertificate (line 220) | struct TLSCertificate
type TLSPacket (line 221) | struct TLSPacket
type TLSContext (line 221) | struct TLSContext
type TLSPacket (line 222) | struct TLSPacket
type TLSPacket (line 223) | struct TLSPacket
type TLSPacket (line 224) | struct TLSPacket
type TLSPacket (line 225) | struct TLSPacket
type TLSPacket (line 226) | struct TLSPacket
type TLSPacket (line 227) | struct TLSPacket
type TLSPacket (line 228) | struct TLSPacket
type TLSContext (line 235) | struct TLSContext
type TLSContext (line 237) | struct TLSContext
type TLSContext (line 240) | struct TLSContext
type TLSContext (line 243) | struct TLSContext
type TLSContext (line 251) | struct TLSContext
type TLSContext (line 253) | struct TLSContext
type ECCCurveParameters (line 254) | struct ECCCurveParameters
type TLSContext (line 254) | struct TLSContext
type ECCCurveParameters (line 254) | struct ECCCurveParameters
type TLSContext (line 257) | struct TLSContext
type TLSContext (line 257) | struct TLSContext
type TLSContext (line 259) | struct TLSContext
type TLSContext (line 260) | struct TLSContext
type TLSContext (line 261) | struct TLSContext
type TLSContext (line 262) | struct TLSContext
type TLSContext (line 263) | struct TLSContext
type TLSContext (line 264) | struct TLSContext
type TLSContext (line 265) | struct TLSContext
type TLSContext (line 266) | struct TLSContext
type TLSPacket (line 267) | struct TLSPacket
type TLSContext (line 267) | struct TLSContext
type TLSPacket (line 268) | struct TLSPacket
type TLSContext (line 268) | struct TLSContext
type TLSPacket (line 269) | struct TLSPacket
type TLSContext (line 269) | struct TLSContext
type TLSPacket (line 270) | struct TLSPacket
type TLSContext (line 270) | struct TLSContext
type TLSPacket (line 271) | struct TLSPacket
type TLSContext (line 271) | struct TLSContext
type TLSContext (line 272) | struct TLSContext
type TLSContext (line 273) | struct TLSContext
type TLSContext (line 274) | struct TLSContext
type TLSContext (line 275) | struct TLSContext
type TLSContext (line 276) | struct TLSContext
type TLSContext (line 277) | struct TLSContext
type TLSContext (line 278) | struct TLSContext
type TLSContext (line 279) | struct TLSContext
type TLSContext (line 280) | struct TLSContext
type TLSCertificate (line 281) | struct TLSCertificate
type TLSCertificate (line 281) | struct TLSCertificate
type TLSCertificate (line 282) | struct TLSCertificate
type TLSContext (line 283) | struct TLSContext
type TLSCertificate (line 283) | struct TLSCertificate
type TLSContext (line 290) | struct TLSContext
type TLSContext (line 297) | struct TLSContext
type TLSPacket (line 298) | struct TLSPacket
type TLSContext (line 298) | struct TLSContext
type TLSPacket (line 299) | struct TLSPacket
type TLSContext (line 299) | struct TLSContext
type TLSPacket (line 300) | struct TLSPacket
type TLSContext (line 300) | struct TLSContext
type TLSPacket (line 301) | struct TLSPacket
type TLSContext (line 301) | struct TLSContext
type TLSPacket (line 302) | struct TLSPacket
type TLSContext (line 302) | struct TLSContext
type TLSContext (line 303) | struct TLSContext
type TLSContext (line 304) | struct TLSContext
type TLSPacket (line 305) | struct TLSPacket
type TLSContext (line 305) | struct TLSContext
type TLSContext (line 322) | struct TLSContext
type TLSContext (line 323) | struct TLSContext
type TLSContext (line 324) | struct TLSContext
type TLSContext (line 327) | struct TLSContext
type TLSContext (line 335) | struct TLSContext
type TLSContext (line 337) | struct TLSContext
type TLSContext (line 338) | struct TLSContext
type TLSContext (line 339) | struct TLSContext
type TLSContext (line 340) | struct TLSContext
type TLSContext (line 341) | struct TLSContext
type TLSContext (line 342) | struct TLSContext
type TLSContext (line 343) | struct TLSContext
type TLSContext (line 344) | struct TLSContext
type TLSContext (line 345) | struct TLSContext
type TLSCertificate (line 345) | struct TLSCertificate
type TLSContext (line 347) | struct TLSContext
type TLSContext (line 348) | struct TLSContext
type TLSContext (line 349) | struct TLSContext
type TLSContext (line 351) | struct TLSContext
type TLSContext (line 352) | struct TLSContext
type TLSContext (line 353) | struct TLSContext
type TLSContext (line 361) | struct TLSContext
type SSL_CTX (line 366) | typedef struct TLSContext SSL_CTX;
type SSL (line 367) | typedef struct TLSContext SSL;
type SSLUserData (line 375) | typedef struct {
type TLSContext (line 392) | struct TLSContext
type TLSContext (line 392) | struct TLSContext
type TLSContext (line 393) | struct TLSContext
type TLSContext (line 394) | struct TLSContext
type TLSContext (line 395) | struct TLSContext
type TLSContext (line 396) | struct TLSContext
type TLSContext (line 397) | struct TLSContext
type TLSContext (line 398) | struct TLSContext
type TLSContext (line 399) | struct TLSContext
type TLSContext (line 400) | struct TLSContext
type TLSContext (line 401) | struct TLSContext
type TLSContext (line 402) | struct TLSContext
type TLSContext (line 403) | struct TLSContext
type TLSContext (line 404) | struct TLSContext
type TLSContext (line 405) | struct TLSContext
type TLSContext (line 406) | struct TLSContext
type TLSContext (line 407) | struct TLSContext
type TLSContext (line 408) | struct TLSContext
type TLSContext (line 409) | struct TLSContext
type TLSContext (line 410) | struct TLSContext
type TLSContext (line 411) | struct TLSContext
type SRTPContext (line 415) | struct SRTPContext
type SRTPContext (line 421) | struct SRTPContext
type SRTPContext (line 422) | struct SRTPContext
type SRTPContext (line 423) | struct SRTPContext
type SRTPContext (line 424) | struct SRTPContext
type SRTPContext (line 425) | struct SRTPContext
type SRTPContext (line 426) | struct SRTPContext
Condensed preview — 10 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,617K chars).
[
{
"path": ".gitignore",
"chars": 44,
"preview": "bak\nbak/*\ntest\ntest/*\ntest.*\ncarl\nmpw\nmpw/*\n"
},
{
"path": "CHANGELOG.md",
"chars": 2636,
"preview": "# Changelog\n\n## 2.2\n\n- \"Crypto Ancienne Meets the Hooded Fang\"\n\n- New ports to classic MacOS/MPW and AmigaOS, and contri"
},
{
"path": "README.md",
"chars": 17694,
"preview": "# Crypto Ancienne: TLS for the Internet of Old Things\n\nCopyright (C) 2020-3 Cameron Kaiser and Contributors. All rights "
},
{
"path": "carl.1",
"chars": 7169,
"preview": ".TH carl 1 \"Crypto Ancienne\"\n\n.SH NAME\ncarl \\- Crypto Ancienne Resource Loader\n\n.SH SYNOPSIS\n.B carl\n.RI [ options ]\n\\fI"
},
{
"path": "carl.c",
"chars": 32318,
"preview": "/*\n * Crypto Ancienne Resource Loader \"carl\" (and example application)\n * Copyright 2020-3 Cameron Kaiser and contributo"
},
{
"path": "carl.md",
"chars": 7479,
"preview": "# carl(1) - Crypto Ancienne Resource Loader\n\nCrypto Ancienne\n\n```\ncarl [options] url\n```\n\n\n<a name=\"description\"></a>\n\n#"
},
{
"path": "carl_mpw.sit.hqx",
"chars": 2486,
"preview": "(This file must be converted with BinHex 4.0)\r:\"fe`GbjcDA3!8dP8090*9#%!N!3(2`#3\"!GM8h4eCQC*G#!SBbNa16Nh,6)`-$)\rJ3@aKC'4T"
},
{
"path": "cryanc.c",
"chars": 1469570,
"preview": "/* Crypto Ancienne v2.0\n A pre-C99 cryptography library for the Internet of Old Things\n\n DISCLAIMER:\n The use of t"
},
{
"path": "cryanc.h",
"chars": 19491,
"preview": "#ifndef TLSE_H\n#define TLSE_H\n\n/* #define DEBUG */\n\n#define NO_SSL_COMPATIBLE_INTERFACE 1\n/* doesn't currently work */\n/"
},
{
"path": "debughello",
"chars": 4493,
"preview": "#!/usr/bin/perl -s\n\nsub assert {\n\tmy $code = shift;\n\tmy $xpl = shift;\n\tif ($warn) {\n\t\teval $code || (warn(\"assertion fai"
}
]
About this extraction
This page contains the full source code of the classilla/cryanc GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 10 files (1.5 MB), approximately 480.3k tokens, and a symbol index with 1034 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.