Compare commits

...
104 Commits
Author SHA1 Message Date
dgp 68061dfef2 Merge forward to demonstrate the test fails after the bug arrived. 2019-03-07 20:05:01 +00:00
dgp 781c32ac29 [39fed4dae5] Proposed test 2019-03-07 20:02:09 +00:00
jan.nijtmans 0801e742ab Fix some "scan.test" test-cases when TCL_UTF_MAX=4. Wrongly resolved merge-conflict in previous cherry-pick merge. 2019-03-02 16:35:26 +00:00
jan.nijtmans bfaca50963 Backport [bd94500678e837d7] from 8.7, preventing endless loops in UTF-8 conversions when handling surrogates. Only effective when compiling with -DTCL_UTF_MAX=4|6 (default: 3). Meant for benefit of Androwish. 2019-03-02 16:04:59 +00:00
jan.nijtmans cc3041cee0 Update all internal tables to Unicode 12.0 2019-03-01 20:11:33 +00:00
jan.nijtmans 809bbc79fb Update internal tables to Unicode 12.0 2019-03-01 20:10:43 +00:00
jan.nijtmans a29e4e5b15 Merge 8.5 2019-02-25 21:12:53 +00:00
jan.nijtmans 82c3e7df6d Move from trusty -> xenal for travis builds. Also add build on Mojave (xcode 10.2) 2019-02-24 18:40:32 +00:00
jan.nijtmans dc75a4866c Merge 8.5 2019-02-24 17:15:51 +00:00
jan.nijtmans 6806ca9630 No longer run socket test-cases on travis with OSX: There are too many random failures/hangups. 2019-02-24 17:05:14 +00:00
jan.nijtmans 886343e50b Fix some comments: "upper" -> "high" (when talking about surrogates) 2019-02-19 20:12:06 +00:00
jan.nijtmans d273753223 Don't use TclUniCharIsSpace() in command-line handling: the windows command-line is not aware of Unicode spaces, only ASCII ones. 2019-02-18 20:38:23 +00:00
jan.nijtmans 04ed7f99da Update libtommath to latest stable release (1.1.0) 2019-02-01 20:00:04 +00:00
sebres 99be2974c3 merge fix [e3f481f187] regression to lookup non-ASCII proc/lambda formal arguments (TclCreateProc/TclPushVarName) 2019-02-01 13:20:57 +00:00
jan.nijtmans 3aabb2ae35 Fix [0238027108]: Tcl_ParseArgsObjv TCL_ARGV_CONSTANT documentation error 2019-01-31 21:01:25 +00:00
sebres 272e429c2c TclPushVarName: rewritten iterators over token-strings considering utf-8 multi-bytes. 2019-01-31 16:22:45 +00:00
sebres fc5dc8e811 code review with small amend (note nameLength is number of bytes, the argument may be utf-8 as well as not necessarily a NTS, so access of char after end may cause segfault). 2019-01-31 12:52:56 +00:00
sebres 8a8e70d5a6 fixes utf-8 compatibility of proc/lambda arguments (regression on compiled locals/variables containing utf-8 characters) - CompiledLocal::nameLength is length in bytes not in chars everywhere in tcl;
simplest example:
  % apply {{€} { set "€" }} 1; # or apply [list \u20ac { set \u20ac }] 1
  can't read "€": no such variable
2019-01-30 20:32:18 +00:00
sebres 3621a3fd74 merge 8.5 2019-01-28 16:15:07 +00:00
sebres 1dec12d618 fixes [4ee9b4f3e965a7da5133]: result of command time overflows by single iteration longer as 35 minutes (uses wide-int instead of int as result now). 2019-01-28 16:12:56 +00:00
pooryorick 0f700f0067 Remove unnecessary inclusion of tclPort.h in tclIntDecls.h 2019-01-26 20:58:24 +00:00
jan.nijtmans fa64afb29a Replace isspace() -> TclIsSpaceProc() _everywhere_.
Change TclIsSpaceProc() and TclIsBareWord so it works with both signed and unsigned characters. Actually, this is not a signature change, as "char" arguments are enlarged to "int" by the C-compiler anyway.
2019-01-26 16:50:21 +00:00
dkf 5f4d728863 Do not assume that literals have a non-NULL bytes field; user code could purge it. 2019-01-25 13:58:07 +00:00
dkf 523ea309ce Do not assume that literals have a non-NULL bytes field; user code could purge it. 2019-01-25 13:43:59 +00:00
jan.nijtmans c1065a28f9 Remove some mac OSX pre-10.4 stuff, which is outdated: current build doesn't support this anymore 2019-01-22 16:52:56 +00:00
sebres 4aca9276df normalize package provide for tcltests 0.1 (declaration moved from pkgIndex.tcl to package source) 2019-01-14 19:51:02 +00:00
sebres ae312970b6 mingw/win-autoconf build: provide tcltest-executable (for consistency reasons); normalizes loading packages calls in test-suite, added build of helpers tcltest (tcltest.cmd) to start tcl-test suite (with all dependencies/facilities) from shell 2019-01-14 17:04:24 +00:00
sebres 6933dc6991 win: allows testchmod to reset DELETE DACL-mask (repaired several tests winFCmd-6.*, winFCmd-9.3, that should catch EACCESS) 2019-01-14 10:00:46 +00:00
sebres 0e3cc87362 minor optimization: check length instead of content - don't touch other memory (so potentially fewer cpu-cache washout's) 2019-01-14 08:55:49 +00:00
jan.nijtmans 631a3b78cb Slightly simpler test for empty string, still covering all cases. Also prepare testpurebytesobj for strings >2G 2019-01-13 15:37:42 +00:00
sebres ae556e2203 provided test-cases covering crash fixed by [58c46e74b931d3a1], as well as new test-facility "testpurebytesobj" allowing creation pure bytes object without internal representations (NULL). 2019-01-11 16:29:24 +00:00
jan.nijtmans 73442469a2 Fix crash reported by reported by François Vogel related to: [cc1e91552c0ca1817292d951f8c694b28c2b2251|cc1e91552c] 2019-01-11 14:35:40 +00:00
sebres 4693981b23 closes [cc1e91552c]: fixes lrange instruction on empty not canonical list (and acc. within expansion also) 2019-01-09 10:01:35 +00:00
sebres cc6df875d6 fixed missing dependency in test-cases "*io-60.1" (constraint-related) - missed load of tcltest-library in sub-process 2019-01-08 18:15:30 +00:00
sebres 9ad3d4b7b1 amend to [a87460dbd4], added clean-up to avoid error {can't set "a(x)": variable isn't array} on next iteration of noComp loop. 2019-01-08 14:39:59 +00:00
sebres 97ef187e5b closes [cc1e91552c]: fixes lrange instruction on empty list, return original list only if it is canonical (otherwise new list object) 2019-01-08 13:35:03 +00:00
sebres 1d20d5be0d bug [cc1e91552c]: added test cases showing the regression (expansion & lrange) 2019-01-08 13:29:29 +00:00
sebres 8692d794c4 merge back after cherry-picking (no functional changes) 2019-01-07 01:15:02 +00:00
sebres b4745088b1 cherry-pick [3e4d907d8e] from 8.6: prevent buffer overrun in fast_s_mp_mul_digs(). 2019-01-07 01:11:32 +00:00
jan.nijtmans 9fd97a3b30 Merge 8.5 2019-01-04 22:36:15 +00:00
jan.nijtmans e0908c3226 Update TZ info to tzdata2018i. 2019-01-04 22:29:03 +00:00
jan.nijtmans 13ae5915d6 Fix signed<->unsigned comparsion warning (occurring in some gcc compilation flags).
Micro-optimization: Use char array in stead of const char pointer for static variable.
2019-01-04 22:23:27 +00:00
jan.nijtmans 2593fcb11c Fix conflict with timezone() function in some MSVC versions 2019-01-03 20:48:38 +00:00
jan.nijtmans ae279a393f Fix conflict with timezone() function in some MSVC versions 2019-01-03 20:47:40 +00:00
José Ignacio Marín 5004f536d3 Update TZ info to tzdata2018i. 2018-12-31 10:50:48 +00:00
jan.nijtmans a1351d366d Fix [3cf3a939d32707e100e06e23806e13569856286a|3cf3a939d3]: timezone deprecated in vc2017.
Also remove unix/config.status.lineno, which was -apparently - checked-in by accident in previous commit
2018-12-30 22:47:44 +00:00
jan.nijtmans 84425899dd Fix [3cf3a939d32707e100e06e23806e13569856286a|3cf3a939d3]: timezone deprecated in vc2017 2018-12-30 22:44:22 +00:00
José Ignacio Marín b5a9fff0ac Update TZ info to tzdata2018h. 2018-12-29 23:15:58 +00:00
sebres b226057ffc clock.test: resolve sporadic timing issues - "after 10" could cause pause >120ms on some platforms (especially on heavily loaded systems), so used average value of 5 measured intervals and real retrieved time as reference point 2018-12-29 10:03:33 +00:00
sebres 211afcace9 prevent buffer overrun in fast_s_mp_mul_digs(), already fixed in newest libtommath versions. 2018-12-28 21:02:43 +00:00
sebres 0513ee0141 resolve warnings: array subscript -1 is below array bounds of 'void *[1]' [-Warray-bounds] if compiled with newest gcc 2018-12-28 19:54:42 +00:00
jan.nijtmans c00086981f New test-cases (backported from 8.7) adapted for pre-TIP-502 behavior 2018-12-20 20:04:01 +00:00
jan.nijtmans 12f94f7a7a (cherry-pick) relax the timings of 2 tests, which incidentally fail on Travis CI.
Also backport a few new test-cases, adapted to match pre-TIP-502 behavior.
2018-12-20 08:06:20 +00:00
jan.nijtmans 878077e3b0 Merge 8.5 2018-12-18 19:52:19 +00:00
jan.nijtmans 4b795b56c8 No need for latest "rvm" any more in osx builds (now even gives an error)
Remove unused/empty header-file
2018-12-18 19:49:09 +00:00
dkf f55b154644 Why are we using rvm? Why? 2018-12-14 13:12:17 +00:00
jan.nijtmans b3f8bdaff2 relax the timings of 2 tests, which incidentally fail on Travis CI 2018-11-29 21:06:45 +00:00
dkf 72fca75fb1 Make the type casting in TclSpellFix less horrific. It's still bad, but it is no longer ghastly. 2018-11-28 11:37:03 +00:00
sebres 5c59a6a505 fixed typo in prepro #ifdef unix || __APPLE__ 2018-11-22 14:44:16 +00:00
sebres fb0f0b6c37 merge 8.5: fixes segfault [7a9dc52b29] and wrong normalization (inside TclJoinPath) for pure relative path-segments; test-cases extended and several windows-related are fixed. 2018-11-22 13:58:37 +00:00
sebres e4f3ce78e3 win/Makefile.in (mingw/gcc toolchains): fixes make mode "tcltest" - added dependencies to build tcl (dlls) also. 2018-11-22 12:58:16 +00:00
sebres dccc93bfb8 fixes segfault [7a9dc52b29] and wrong normalization (inside TclJoinPath) for pure relative path-segments;
test-cases extended and several windows-related are fixed.
2018-11-22 12:48:42 +00:00
sebres a89cd349f1 prepare merge: TclJoinPath is in internal API (MODULE_SCOPE) since 8.6 and static (used locally in tclPathObj) in 8.5 2018-11-22 12:45:04 +00:00
sebres e02fb5a67b win: repair test command "testchmod": correct load module (ADVAPI32 for x86/x64) and fix readonly mask (don't deny DELETE mask, test cleanup should be able to delete entry) 2018-11-21 10:00:54 +00:00
sebres 8c233c93c1 win: fixed pwd-related test-cases in winPipe.test: several test-cases expect current directory equals [temporaryDirectory] 2018-11-20 20:56:50 +00:00
sebres 0e5ff41021 win: fixes case sensitivity of glob test cases (winFile-2.*): current directory can be different as [temporaryDirectory] (if parameter -tmpdir specified). 2018-11-20 20:23:22 +00:00
sebres 23102369d1 refactoring normalize in case of second path starting with tilde (~/~foo) - force second path as relative by join (provide normalize flag for TclJoinPath);
test cases extended
2018-11-20 20:11:02 +00:00
sebres 1aa5869ece fixes segfault [7a9dc52b29]: unexpected decrement of the ref-count after TclJoinPath 2018-11-20 18:02:32 +00:00
dkf e537ff7be6 More coverity issues 2018-11-20 13:51:38 +00:00
dgp 35299947e3 merge release 2018-11-16 20:26:14 +00:00
dgp 38f743a2c7 [00d04c4f12] Repair broken edge cases in [binary encode base64]. 2018-11-16 18:45:59 +00:00
dgp 4a6019f7a6 [00d04c4f12] Repair broken edge cases in [binary encode base64]. 2018-11-16 18:38:35 +00:00
dkf fa3d7ed178 Clear up a bunch of small issues found by Coverity analysis. 2018-11-16 13:45:26 +00:00
sebres d1e5b0f72f fixes segfault [00d04c4f12], unfulfilled base64 (strict and non-strict mode, etc). 2018-11-15 22:31:39 +00:00
sebres dca8be01de test cases for decode base64, bug [00d04c4f12], unfulfilled base64 (strict and non-strict mode, etc). 2018-11-15 22:18:29 +00:00
dgp f2d42d756e merge release 2018-11-15 16:55:13 +00:00
dgp 54488f1714 close fork 2018-11-15 16:35:58 +00:00
dgp 5b4a1fcaf3 merge 8.5 2018-11-15 16:34:44 +00:00
jan.nijtmans 5e8ed94397 Make Tcl_WinTCharToUtf/Tcl_WinUtfToTChar work (again) with TCL_UTF_MAX=6. No effect when TCL_UTF_MAX=3|4 2018-11-15 08:05:23 +00:00
dkf 4402274b45 Make socket tests less likely to hang on OSX 2018-11-14 03:31:58 +00:00
dkf 77a9cc76b1 Properly switch on running tests on Travis. CI builds now debugged. 2018-11-12 09:51:45 +00:00
dkf fc38a30572 Cleaner way of writing environment variables 2018-11-12 09:49:24 +00:00
dkf 18b503297b Fix brokenness in GNUmakefile 2018-11-12 09:26:25 +00:00
dkf 44fd5b0f83 Fix builds on Travis. 2018-11-11 16:55:53 +00:00
dkf 13f704914a Clean up Travis config now that it passes 2018-11-11 15:07:12 +00:00
dkf 3166f1ad45 merge 8.6 2018-11-10 10:22:19 +00:00
dkf b82e966961 Build instructions tinkering 2018-11-10 09:55:31 +00:00
dkf 6fe99b6e66 Tracking down test failures 2018-11-10 09:39:35 +00:00
dkf cbbc8d66b8 Make the macosx build able to succeed 2018-11-10 07:29:08 +00:00
dgp 5deb25bc9b merge 8.5 2018-11-09 16:03:22 +00:00
dgp 0f4e877214 [35a8f1c04a] Fix bad lengths when creating string rep of some lists. 2018-11-09 16:00:57 +00:00
dgp 4df4dafad6 Additional test 2018-11-09 15:47:37 +00:00
dgp 83ec300abd Revise bug fix to support (length == 0) correctly.
Added comments and improved safety in caller.
2018-11-09 15:39:26 +00:00
sebres ddae61a859 closes [35a8f1c04a]: minimalist fix - beware of discrepancy between TclScanElement and TclConvertElement (prefer braces considering TCL_DONT_QUOTE_HASH in case of first list element) 2018-11-09 14:19:08 +00:00
sebres 75399e97a8 test case to cover bug [35a8f1c04a] 2018-11-09 14:13:15 +00:00
dgp 008a36f3e4 merge mark 2018-11-08 17:07:01 +00:00
dgp 5471354571 [86d249bcba] Make sure that tcltest::runAllTests actually returns 1 on failure.
Repairs TIP 525 Implementation.
2018-11-08 17:05:00 +00:00
dkf 155f409a38 Merge the Travis build rules more properly 2018-11-07 19:22:20 +00:00
dkf 20c06fad80 merge 8.6 branch 2018-11-07 19:04:53 +00:00
dkf a6d8a3e498 [86d249bcba] Make sure that tcltest::runAllTests actually returns 1 on failure 2018-11-07 18:56:14 +00:00
dkf c1c94e4437 [86d249bcba] Make sure that tcltest::runAllTests actually returns 1 on failure 2018-11-07 18:50:09 +00:00
dkf c5bbe85f29 Rebase of travis config 2018-11-07 13:25:45 +00:00
jan.nijtmans bea160e7f6 Start building this branch with Travis. See how far we get 2018-11-01 20:18:12 +00:00
jan.nijtmans b3dceb5360 Make MacOSX compile work (hopefully) and cross-compile on mingw-w64 (compile only, no unit-test yet) 2018-10-31 21:02:42 +00:00
249 changed files with 31421 additions and 16991 deletions
+138
View File
@@ -0,0 +1,138 @@
sudo: false
language: c
matrix:
include:
- os: linux
dist: xenial
compiler: clang
env:
- BUILD_DIR=unix
- os: linux
dist: xenial
compiler: clang
env:
- CFGOPT=--disable-shared
- BUILD_DIR=unix
- os: linux
dist: xenial
compiler: gcc
env:
- BUILD_DIR=unix
- os: linux
dist: xenial
compiler: gcc
env:
- CFGOPT=--disable-shared
- BUILD_DIR=unix
- os: linux
dist: xenial
compiler: gcc-4.9
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-4.9
env:
- BUILD_DIR=unix
- os: linux
dist: xenial
compiler: gcc-5
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-5
env:
- BUILD_DIR=unix
- os: linux
dist: xenial
compiler: gcc-6
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-6
env:
- BUILD_DIR=unix
- os: linux
dist: xenial
compiler: gcc-7
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-7
env:
- BUILD_DIR=unix
- os: osx
osx_image: xcode8
env:
- BUILD_DIR=unix
- os: osx
osx_image: xcode8
env:
- BUILD_DIR=macosx
- NO_DIRECT_CONFIGURE=1
- os: osx
osx_image: xcode9
env:
- BUILD_DIR=macosx
- NO_DIRECT_CONFIGURE=1
- os: osx
osx_image: xcode10.2
env:
- BUILD_DIR=macosx
- NO_DIRECT_CONFIGURE=1
### C builds not currently supported on Windows instances
# - os: windows
# env:
# - BUILD_DIR=win
### ... so proxy with a Mingw cross-compile
# Test with mingw-w64 (32 bit)
- os: linux
dist: xenial
compiler: i686-w64-mingw32-gcc
addons:
apt:
packages:
- gcc-mingw-w64-base
- binutils-mingw-w64-i686
- gcc-mingw-w64-i686
- gcc-mingw-w64
- gcc-multilib
- wine
env:
- BUILD_DIR=win
- CFGOPT=--host=i686-w64-mingw32
- NO_DIRECT_TEST=1
# Test with mingw-w64 (64 bit)
- os: linux
dist: xenial
compiler: x86_64-w64-mingw32-gcc
addons:
apt:
packages:
- gcc-mingw-w64-base
- binutils-mingw-w64-x86-64
- gcc-mingw-w64-x86-64
- gcc-mingw-w64
- wine
env:
- BUILD_DIR=win
- CFGOPT="--host=x86_64-w64-mingw32 --enable-64bit"
- NO_DIRECT_TEST=1
before_install:
- export ERROR_ON_FAILURES=1
- cd ${BUILD_DIR}
install:
- test -n "$NO_DIRECT_CONFIGURE" || ./configure ${CFGOPT}
script:
- make
# The styles=develop avoids some weird problems on OSX
- test -n "$NO_DIRECT_TEST" || make test styles=develop
+2
View File
@@ -8891,4 +8891,6 @@ improvements to regexp engine from Postgres (lane,porter,fellows,seltenreich)
2018-11-09 (bug)[35a8f1] overlong string length of some lists (owens)
2018-11-16 (bug)[00d04c] Repair [binary encode base64] (sebres)
- Released 8.6.9, November 16, 2018 - details at http://core.tcl-lang.org/tcl/ -
+1 -1
View File
@@ -53,7 +53,7 @@ strtol(
*/
p = string;
while (isspace(UCHAR(*p))) {
while (TclIsSpaceProc(*p)) {
p += 1;
}
+1 -1
View File
@@ -74,7 +74,7 @@ strtoul(
*/
p = string;
while (isspace(UCHAR(*p))) {
while (TclIsSpaceProc(*p)) {
p += 1;
}
if (*p == '-') {
+1 -1
View File
@@ -97,7 +97,7 @@ void change_file_date(filename,dosdate,tmu_date)
SetFileTime(hFile,&ftm,&ftLastAcc,&ftm);
CloseHandle(hFile);
#else
#ifdef unix || __APPLE__
#if defined(unix) || defined(__APPLE__)
struct utimbuf ut;
struct tm newdate;
newdate.tm_sec = tmu_date.tm_sec;
+1 -1
View File
@@ -94,7 +94,7 @@ uLong filetime(f, tmzip, dt)
return ret;
}
#else
#ifdef unix || __APPLE__
#if defined(unix) || defined(__APPLE__)
uLong filetime(f, tmzip, dt)
char *f; /* name of file to get info on */
tm_zip *tmzip; /* return value: access, modific. and creation times */
+3 -3
View File
@@ -3,7 +3,7 @@
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
'\"
.TH Tcl_ParseArgsObjv 3 8.6 Tcl "Tcl Library Procedures"
.so man.macros
.BS
@@ -103,8 +103,8 @@ the argument's value. The following values are acceptable values for
\fBTCL_ARGV_CONSTANT\fR
.
The argument does not take any following value argument. If this argument is
present, the int pointed to by the \fIsrcPtr\fR field is copied to the
\fIdstPtr\fR field. The \fIclientData\fR field is ignored.
present, the \fIsrcPtr\fR field (casted to \fIint\fR) is copied to the variable
pointed to by the \fIdstPtr\fR field. The \fIclientData\fR field is ignored.
.TP
\fBTCL_ARGV_END\fR
.
+177 -172
View File
@@ -153,46 +153,46 @@ static const crange alphaRangeTable[] = {
{0xc92, 0xca8}, {0xcaa, 0xcb3}, {0xcb5, 0xcb9}, {0xd05, 0xd0c},
{0xd0e, 0xd10}, {0xd12, 0xd3a}, {0xd54, 0xd56}, {0xd5f, 0xd61},
{0xd7a, 0xd7f}, {0xd85, 0xd96}, {0xd9a, 0xdb1}, {0xdb3, 0xdbb},
{0xdc0, 0xdc6}, {0xe01, 0xe30}, {0xe40, 0xe46}, {0xe94, 0xe97},
{0xe99, 0xe9f}, {0xea1, 0xea3}, {0xead, 0xeb0}, {0xec0, 0xec4},
{0xedc, 0xedf}, {0xf40, 0xf47}, {0xf49, 0xf6c}, {0xf88, 0xf8c},
{0x1000, 0x102a}, {0x1050, 0x1055}, {0x105a, 0x105d}, {0x106e, 0x1070},
{0x1075, 0x1081}, {0x10a0, 0x10c5}, {0x10d0, 0x10fa}, {0x10fc, 0x1248},
{0x124a, 0x124d}, {0x1250, 0x1256}, {0x125a, 0x125d}, {0x1260, 0x1288},
{0x128a, 0x128d}, {0x1290, 0x12b0}, {0x12b2, 0x12b5}, {0x12b8, 0x12be},
{0x12c2, 0x12c5}, {0x12c8, 0x12d6}, {0x12d8, 0x1310}, {0x1312, 0x1315},
{0x1318, 0x135a}, {0x1380, 0x138f}, {0x13a0, 0x13f5}, {0x13f8, 0x13fd},
{0x1401, 0x166c}, {0x166f, 0x167f}, {0x1681, 0x169a}, {0x16a0, 0x16ea},
{0x16f1, 0x16f8}, {0x1700, 0x170c}, {0x170e, 0x1711}, {0x1720, 0x1731},
{0x1740, 0x1751}, {0x1760, 0x176c}, {0x176e, 0x1770}, {0x1780, 0x17b3},
{0x1820, 0x1878}, {0x1880, 0x1884}, {0x1887, 0x18a8}, {0x18b0, 0x18f5},
{0x1900, 0x191e}, {0x1950, 0x196d}, {0x1970, 0x1974}, {0x1980, 0x19ab},
{0x19b0, 0x19c9}, {0x1a00, 0x1a16}, {0x1a20, 0x1a54}, {0x1b05, 0x1b33},
{0x1b45, 0x1b4b}, {0x1b83, 0x1ba0}, {0x1bba, 0x1be5}, {0x1c00, 0x1c23},
{0x1c4d, 0x1c4f}, {0x1c5a, 0x1c7d}, {0x1c80, 0x1c88}, {0x1c90, 0x1cba},
{0x1cbd, 0x1cbf}, {0x1ce9, 0x1cec}, {0x1cee, 0x1cf1}, {0x1d00, 0x1dbf},
{0x1e00, 0x1f15}, {0x1f18, 0x1f1d}, {0x1f20, 0x1f45}, {0x1f48, 0x1f4d},
{0x1f50, 0x1f57}, {0x1f5f, 0x1f7d}, {0x1f80, 0x1fb4}, {0x1fb6, 0x1fbc},
{0x1fc2, 0x1fc4}, {0x1fc6, 0x1fcc}, {0x1fd0, 0x1fd3}, {0x1fd6, 0x1fdb},
{0x1fe0, 0x1fec}, {0x1ff2, 0x1ff4}, {0x1ff6, 0x1ffc}, {0x2090, 0x209c},
{0x210a, 0x2113}, {0x2119, 0x211d}, {0x212a, 0x212d}, {0x212f, 0x2139},
{0x213c, 0x213f}, {0x2145, 0x2149}, {0x2c00, 0x2c2e}, {0x2c30, 0x2c5e},
{0x2c60, 0x2ce4}, {0x2ceb, 0x2cee}, {0x2d00, 0x2d25}, {0x2d30, 0x2d67},
{0x2d80, 0x2d96}, {0x2da0, 0x2da6}, {0x2da8, 0x2dae}, {0x2db0, 0x2db6},
{0x2db8, 0x2dbe}, {0x2dc0, 0x2dc6}, {0x2dc8, 0x2dce}, {0x2dd0, 0x2dd6},
{0x2dd8, 0x2dde}, {0x3031, 0x3035}, {0x3041, 0x3096}, {0x309d, 0x309f},
{0x30a1, 0x30fa}, {0x30fc, 0x30ff}, {0x3105, 0x312f}, {0x3131, 0x318e},
{0x31a0, 0x31ba}, {0x31f0, 0x31ff}, {0x3400, 0x4db5}, {0x4e00, 0x9fef},
{0xa000, 0xa48c}, {0xa4d0, 0xa4fd}, {0xa500, 0xa60c}, {0xa610, 0xa61f},
{0xa640, 0xa66e}, {0xa67f, 0xa69d}, {0xa6a0, 0xa6e5}, {0xa717, 0xa71f},
{0xa722, 0xa788}, {0xa78b, 0xa7b9}, {0xa7f7, 0xa801}, {0xa803, 0xa805},
{0xdc0, 0xdc6}, {0xe01, 0xe30}, {0xe40, 0xe46}, {0xe86, 0xe8a},
{0xe8c, 0xea3}, {0xea7, 0xeb0}, {0xec0, 0xec4}, {0xedc, 0xedf},
{0xf40, 0xf47}, {0xf49, 0xf6c}, {0xf88, 0xf8c}, {0x1000, 0x102a},
{0x1050, 0x1055}, {0x105a, 0x105d}, {0x106e, 0x1070}, {0x1075, 0x1081},
{0x10a0, 0x10c5}, {0x10d0, 0x10fa}, {0x10fc, 0x1248}, {0x124a, 0x124d},
{0x1250, 0x1256}, {0x125a, 0x125d}, {0x1260, 0x1288}, {0x128a, 0x128d},
{0x1290, 0x12b0}, {0x12b2, 0x12b5}, {0x12b8, 0x12be}, {0x12c2, 0x12c5},
{0x12c8, 0x12d6}, {0x12d8, 0x1310}, {0x1312, 0x1315}, {0x1318, 0x135a},
{0x1380, 0x138f}, {0x13a0, 0x13f5}, {0x13f8, 0x13fd}, {0x1401, 0x166c},
{0x166f, 0x167f}, {0x1681, 0x169a}, {0x16a0, 0x16ea}, {0x16f1, 0x16f8},
{0x1700, 0x170c}, {0x170e, 0x1711}, {0x1720, 0x1731}, {0x1740, 0x1751},
{0x1760, 0x176c}, {0x176e, 0x1770}, {0x1780, 0x17b3}, {0x1820, 0x1878},
{0x1880, 0x1884}, {0x1887, 0x18a8}, {0x18b0, 0x18f5}, {0x1900, 0x191e},
{0x1950, 0x196d}, {0x1970, 0x1974}, {0x1980, 0x19ab}, {0x19b0, 0x19c9},
{0x1a00, 0x1a16}, {0x1a20, 0x1a54}, {0x1b05, 0x1b33}, {0x1b45, 0x1b4b},
{0x1b83, 0x1ba0}, {0x1bba, 0x1be5}, {0x1c00, 0x1c23}, {0x1c4d, 0x1c4f},
{0x1c5a, 0x1c7d}, {0x1c80, 0x1c88}, {0x1c90, 0x1cba}, {0x1cbd, 0x1cbf},
{0x1ce9, 0x1cec}, {0x1cee, 0x1cf3}, {0x1d00, 0x1dbf}, {0x1e00, 0x1f15},
{0x1f18, 0x1f1d}, {0x1f20, 0x1f45}, {0x1f48, 0x1f4d}, {0x1f50, 0x1f57},
{0x1f5f, 0x1f7d}, {0x1f80, 0x1fb4}, {0x1fb6, 0x1fbc}, {0x1fc2, 0x1fc4},
{0x1fc6, 0x1fcc}, {0x1fd0, 0x1fd3}, {0x1fd6, 0x1fdb}, {0x1fe0, 0x1fec},
{0x1ff2, 0x1ff4}, {0x1ff6, 0x1ffc}, {0x2090, 0x209c}, {0x210a, 0x2113},
{0x2119, 0x211d}, {0x212a, 0x212d}, {0x212f, 0x2139}, {0x213c, 0x213f},
{0x2145, 0x2149}, {0x2c00, 0x2c2e}, {0x2c30, 0x2c5e}, {0x2c60, 0x2ce4},
{0x2ceb, 0x2cee}, {0x2d00, 0x2d25}, {0x2d30, 0x2d67}, {0x2d80, 0x2d96},
{0x2da0, 0x2da6}, {0x2da8, 0x2dae}, {0x2db0, 0x2db6}, {0x2db8, 0x2dbe},
{0x2dc0, 0x2dc6}, {0x2dc8, 0x2dce}, {0x2dd0, 0x2dd6}, {0x2dd8, 0x2dde},
{0x3031, 0x3035}, {0x3041, 0x3096}, {0x309d, 0x309f}, {0x30a1, 0x30fa},
{0x30fc, 0x30ff}, {0x3105, 0x312f}, {0x3131, 0x318e}, {0x31a0, 0x31ba},
{0x31f0, 0x31ff}, {0x3400, 0x4db5}, {0x4e00, 0x9fef}, {0xa000, 0xa48c},
{0xa4d0, 0xa4fd}, {0xa500, 0xa60c}, {0xa610, 0xa61f}, {0xa640, 0xa66e},
{0xa67f, 0xa69d}, {0xa6a0, 0xa6e5}, {0xa717, 0xa71f}, {0xa722, 0xa788},
{0xa78b, 0xa7bf}, {0xa7c2, 0xa7c6}, {0xa7f7, 0xa801}, {0xa803, 0xa805},
{0xa807, 0xa80a}, {0xa80c, 0xa822}, {0xa840, 0xa873}, {0xa882, 0xa8b3},
{0xa8f2, 0xa8f7}, {0xa90a, 0xa925}, {0xa930, 0xa946}, {0xa960, 0xa97c},
{0xa984, 0xa9b2}, {0xa9e0, 0xa9e4}, {0xa9e6, 0xa9ef}, {0xa9fa, 0xa9fe},
{0xaa00, 0xaa28}, {0xaa40, 0xaa42}, {0xaa44, 0xaa4b}, {0xaa60, 0xaa76},
{0xaa7e, 0xaaaf}, {0xaab9, 0xaabd}, {0xaadb, 0xaadd}, {0xaae0, 0xaaea},
{0xaaf2, 0xaaf4}, {0xab01, 0xab06}, {0xab09, 0xab0e}, {0xab11, 0xab16},
{0xab20, 0xab26}, {0xab28, 0xab2e}, {0xab30, 0xab5a}, {0xab5c, 0xab65},
{0xab20, 0xab26}, {0xab28, 0xab2e}, {0xab30, 0xab5a}, {0xab5c, 0xab67},
{0xab70, 0xabe2}, {0xac00, 0xd7a3}, {0xd7b0, 0xd7c6}, {0xd7cb, 0xd7fb},
{0xf900, 0xfa6d}, {0xfa70, 0xfad9}, {0xfb00, 0xfb06}, {0xfb13, 0xfb17},
{0xfb1f, 0xfb28}, {0xfb2a, 0xfb36}, {0xfb38, 0xfb3c}, {0xfb46, 0xfbb1},
@@ -213,21 +213,22 @@ static const crange alphaRangeTable[] = {
{0x10a80, 0x10a9c}, {0x10ac0, 0x10ac7}, {0x10ac9, 0x10ae4}, {0x10b00, 0x10b35},
{0x10b40, 0x10b55}, {0x10b60, 0x10b72}, {0x10b80, 0x10b91}, {0x10c00, 0x10c48},
{0x10c80, 0x10cb2}, {0x10cc0, 0x10cf2}, {0x10d00, 0x10d23}, {0x10f00, 0x10f1c},
{0x10f30, 0x10f45}, {0x11003, 0x11037}, {0x11083, 0x110af}, {0x110d0, 0x110e8},
{0x11103, 0x11126}, {0x11150, 0x11172}, {0x11183, 0x111b2}, {0x111c1, 0x111c4},
{0x11200, 0x11211}, {0x11213, 0x1122b}, {0x11280, 0x11286}, {0x1128a, 0x1128d},
{0x1128f, 0x1129d}, {0x1129f, 0x112a8}, {0x112b0, 0x112de}, {0x11305, 0x1130c},
{0x11313, 0x11328}, {0x1132a, 0x11330}, {0x11335, 0x11339}, {0x1135d, 0x11361},
{0x11400, 0x11434}, {0x11447, 0x1144a}, {0x11480, 0x114af}, {0x11580, 0x115ae},
{0x115d8, 0x115db}, {0x11600, 0x1162f}, {0x11680, 0x116aa}, {0x11700, 0x1171a},
{0x11800, 0x1182b}, {0x118a0, 0x118df}, {0x11a0b, 0x11a32}, {0x11a5c, 0x11a83},
{0x11a86, 0x11a89}, {0x11ac0, 0x11af8}, {0x11c00, 0x11c08}, {0x11c0a, 0x11c2e},
{0x11c72, 0x11c8f}, {0x11d00, 0x11d06}, {0x11d0b, 0x11d30}, {0x11d60, 0x11d65},
{0x11d6a, 0x11d89}, {0x11ee0, 0x11ef2}, {0x12000, 0x12399}, {0x12480, 0x12543},
{0x13000, 0x1342e}, {0x14400, 0x14646}, {0x16800, 0x16a38}, {0x16a40, 0x16a5e},
{0x16ad0, 0x16aed}, {0x16b00, 0x16b2f}, {0x16b40, 0x16b43}, {0x16b63, 0x16b77},
{0x16b7d, 0x16b8f}, {0x16e40, 0x16e7f}, {0x16f00, 0x16f44}, {0x16f93, 0x16f9f},
{0x17000, 0x187f1}, {0x18800, 0x18af2}, {0x1b000, 0x1b11e}, {0x1b170, 0x1b2fb},
{0x10f30, 0x10f45}, {0x10fe0, 0x10ff6}, {0x11003, 0x11037}, {0x11083, 0x110af},
{0x110d0, 0x110e8}, {0x11103, 0x11126}, {0x11150, 0x11172}, {0x11183, 0x111b2},
{0x111c1, 0x111c4}, {0x11200, 0x11211}, {0x11213, 0x1122b}, {0x11280, 0x11286},
{0x1128a, 0x1128d}, {0x1128f, 0x1129d}, {0x1129f, 0x112a8}, {0x112b0, 0x112de},
{0x11305, 0x1130c}, {0x11313, 0x11328}, {0x1132a, 0x11330}, {0x11335, 0x11339},
{0x1135d, 0x11361}, {0x11400, 0x11434}, {0x11447, 0x1144a}, {0x11480, 0x114af},
{0x11580, 0x115ae}, {0x115d8, 0x115db}, {0x11600, 0x1162f}, {0x11680, 0x116aa},
{0x11700, 0x1171a}, {0x11800, 0x1182b}, {0x118a0, 0x118df}, {0x119a0, 0x119a7},
{0x119aa, 0x119d0}, {0x11a0b, 0x11a32}, {0x11a5c, 0x11a89}, {0x11ac0, 0x11af8},
{0x11c00, 0x11c08}, {0x11c0a, 0x11c2e}, {0x11c72, 0x11c8f}, {0x11d00, 0x11d06},
{0x11d0b, 0x11d30}, {0x11d60, 0x11d65}, {0x11d6a, 0x11d89}, {0x11ee0, 0x11ef2},
{0x12000, 0x12399}, {0x12480, 0x12543}, {0x13000, 0x1342e}, {0x14400, 0x14646},
{0x16800, 0x16a38}, {0x16a40, 0x16a5e}, {0x16ad0, 0x16aed}, {0x16b00, 0x16b2f},
{0x16b40, 0x16b43}, {0x16b63, 0x16b77}, {0x16b7d, 0x16b8f}, {0x16e40, 0x16e7f},
{0x16f00, 0x16f4a}, {0x16f93, 0x16f9f}, {0x17000, 0x187f7}, {0x18800, 0x18af2},
{0x1b000, 0x1b11e}, {0x1b150, 0x1b152}, {0x1b164, 0x1b167}, {0x1b170, 0x1b2fb},
{0x1bc00, 0x1bc6a}, {0x1bc70, 0x1bc7c}, {0x1bc80, 0x1bc88}, {0x1bc90, 0x1bc99},
{0x1d400, 0x1d454}, {0x1d456, 0x1d49c}, {0x1d4a9, 0x1d4ac}, {0x1d4ae, 0x1d4b9},
{0x1d4bd, 0x1d4c3}, {0x1d4c5, 0x1d505}, {0x1d507, 0x1d50a}, {0x1d50d, 0x1d514},
@@ -235,12 +236,13 @@ static const crange alphaRangeTable[] = {
{0x1d54a, 0x1d550}, {0x1d552, 0x1d6a5}, {0x1d6a8, 0x1d6c0}, {0x1d6c2, 0x1d6da},
{0x1d6dc, 0x1d6fa}, {0x1d6fc, 0x1d714}, {0x1d716, 0x1d734}, {0x1d736, 0x1d74e},
{0x1d750, 0x1d76e}, {0x1d770, 0x1d788}, {0x1d78a, 0x1d7a8}, {0x1d7aa, 0x1d7c2},
{0x1d7c4, 0x1d7cb}, {0x1e800, 0x1e8c4}, {0x1e900, 0x1e943}, {0x1ee00, 0x1ee03},
{0x1ee05, 0x1ee1f}, {0x1ee29, 0x1ee32}, {0x1ee34, 0x1ee37}, {0x1ee4d, 0x1ee4f},
{0x1ee67, 0x1ee6a}, {0x1ee6c, 0x1ee72}, {0x1ee74, 0x1ee77}, {0x1ee79, 0x1ee7c},
{0x1ee80, 0x1ee89}, {0x1ee8b, 0x1ee9b}, {0x1eea1, 0x1eea3}, {0x1eea5, 0x1eea9},
{0x1eeab, 0x1eebb}, {0x20000, 0x2a6d6}, {0x2a700, 0x2b734}, {0x2b740, 0x2b81d},
{0x2b820, 0x2cea1}, {0x2ceb0, 0x2ebe0}, {0x2f800, 0x2fa1d}
{0x1d7c4, 0x1d7cb}, {0x1e100, 0x1e12c}, {0x1e137, 0x1e13d}, {0x1e2c0, 0x1e2eb},
{0x1e800, 0x1e8c4}, {0x1e900, 0x1e943}, {0x1ee00, 0x1ee03}, {0x1ee05, 0x1ee1f},
{0x1ee29, 0x1ee32}, {0x1ee34, 0x1ee37}, {0x1ee4d, 0x1ee4f}, {0x1ee67, 0x1ee6a},
{0x1ee6c, 0x1ee72}, {0x1ee74, 0x1ee77}, {0x1ee79, 0x1ee7c}, {0x1ee80, 0x1ee89},
{0x1ee8b, 0x1ee9b}, {0x1eea1, 0x1eea3}, {0x1eea5, 0x1eea9}, {0x1eeab, 0x1eebb},
{0x20000, 0x2a6d6}, {0x2a700, 0x2b734}, {0x2b740, 0x2b81d}, {0x2b820, 0x2cea1},
{0x2ceb0, 0x2ebe0}, {0x2f800, 0x2fa1d}
#endif
};
@@ -257,24 +259,24 @@ static const chr alphaCharTable[] = {
0xb83, 0xb99, 0xb9a, 0xb9c, 0xb9e, 0xb9f, 0xba3, 0xba4, 0xbd0,
0xc3d, 0xc60, 0xc61, 0xc80, 0xcbd, 0xcde, 0xce0, 0xce1, 0xcf1,
0xcf2, 0xd3d, 0xd4e, 0xdbd, 0xe32, 0xe33, 0xe81, 0xe82, 0xe84,
0xe87, 0xe88, 0xe8a, 0xe8d, 0xea5, 0xea7, 0xeaa, 0xeab, 0xeb2,
0xeb3, 0xebd, 0xec6, 0xf00, 0x103f, 0x1061, 0x1065, 0x1066, 0x108e,
0x10c7, 0x10cd, 0x1258, 0x12c0, 0x17d7, 0x17dc, 0x18aa, 0x1aa7, 0x1bae,
0x1baf, 0x1cf5, 0x1cf6, 0x1f59, 0x1f5b, 0x1f5d, 0x1fbe, 0x2071, 0x207f,
0x2102, 0x2107, 0x2115, 0x2124, 0x2126, 0x2128, 0x214e, 0x2183, 0x2184,
0x2cf2, 0x2cf3, 0x2d27, 0x2d2d, 0x2d6f, 0x2e2f, 0x3005, 0x3006, 0x303b,
0x303c, 0xa62a, 0xa62b, 0xa8fb, 0xa8fd, 0xa8fe, 0xa9cf, 0xaa7a, 0xaab1,
0xaab5, 0xaab6, 0xaac0, 0xaac2, 0xfb1d, 0xfb3e, 0xfb40, 0xfb41, 0xfb43,
0xfb44
0xea5, 0xeb2, 0xeb3, 0xebd, 0xec6, 0xf00, 0x103f, 0x1061, 0x1065,
0x1066, 0x108e, 0x10c7, 0x10cd, 0x1258, 0x12c0, 0x17d7, 0x17dc, 0x18aa,
0x1aa7, 0x1bae, 0x1baf, 0x1cf5, 0x1cf6, 0x1cfa, 0x1f59, 0x1f5b, 0x1f5d,
0x1fbe, 0x2071, 0x207f, 0x2102, 0x2107, 0x2115, 0x2124, 0x2126, 0x2128,
0x214e, 0x2183, 0x2184, 0x2cf2, 0x2cf3, 0x2d27, 0x2d2d, 0x2d6f, 0x2e2f,
0x3005, 0x3006, 0x303b, 0x303c, 0xa62a, 0xa62b, 0xa8fb, 0xa8fd, 0xa8fe,
0xa9cf, 0xaa7a, 0xaab1, 0xaab5, 0xaab6, 0xaac0, 0xaac2, 0xfb1d, 0xfb3e,
0xfb40, 0xfb41, 0xfb43, 0xfb44
#if CHRBITS > 16
,0x1003c, 0x1003d, 0x10808, 0x10837, 0x10838, 0x1083c, 0x108f4, 0x108f5, 0x109be,
0x109bf, 0x10a00, 0x10f27, 0x11144, 0x11176, 0x111da, 0x111dc, 0x11288, 0x1130f,
0x11310, 0x11332, 0x11333, 0x1133d, 0x11350, 0x114c4, 0x114c5, 0x114c7, 0x11644,
0x118ff, 0x11a00, 0x11a3a, 0x11a50, 0x11a9d, 0x11c40, 0x11d08, 0x11d09, 0x11d46,
0x11d67, 0x11d68, 0x11d98, 0x16f50, 0x16fe0, 0x16fe1, 0x1d49e, 0x1d49f, 0x1d4a2,
0x1d4a5, 0x1d4a6, 0x1d4bb, 0x1d546, 0x1ee21, 0x1ee22, 0x1ee24, 0x1ee27, 0x1ee39,
0x1ee3b, 0x1ee42, 0x1ee47, 0x1ee49, 0x1ee4b, 0x1ee51, 0x1ee52, 0x1ee54, 0x1ee57,
0x1ee59, 0x1ee5b, 0x1ee5d, 0x1ee5f, 0x1ee61, 0x1ee62, 0x1ee64, 0x1ee7e
0x11310, 0x11332, 0x11333, 0x1133d, 0x11350, 0x1145f, 0x114c4, 0x114c5, 0x114c7,
0x11644, 0x116b8, 0x118ff, 0x119e1, 0x119e3, 0x11a00, 0x11a3a, 0x11a50, 0x11a9d,
0x11c40, 0x11d08, 0x11d09, 0x11d46, 0x11d67, 0x11d68, 0x11d98, 0x16f50, 0x16fe0,
0x16fe1, 0x16fe3, 0x1d49e, 0x1d49f, 0x1d4a2, 0x1d4a5, 0x1d4a6, 0x1d4bb, 0x1d546,
0x1e14e, 0x1e94b, 0x1ee21, 0x1ee22, 0x1ee24, 0x1ee27, 0x1ee39, 0x1ee3b, 0x1ee42,
0x1ee47, 0x1ee49, 0x1ee4b, 0x1ee51, 0x1ee52, 0x1ee54, 0x1ee57, 0x1ee59, 0x1ee5b,
0x1ee5d, 0x1ee5f, 0x1ee61, 0x1ee62, 0x1ee64, 0x1ee7e
#endif
};
@@ -289,8 +291,8 @@ static const crange controlRangeTable[] = {
{0x202a, 0x202e}, {0x2060, 0x2064}, {0x2066, 0x206f}, {0xe000, 0xf8ff},
{0xfff9, 0xfffb}
#if CHRBITS > 16
,{0x1bca0, 0x1bca3}, {0x1d173, 0x1d17a}, {0xe0020, 0xe007f}, {0xf0000, 0xffffd},
{0x100000, 0x10fffd}
,{0x13430, 0x13438}, {0x1bca0, 0x1bca3}, {0x1d173, 0x1d17a}, {0xe0020, 0xe007f},
{0xf0000, 0xffffd}, {0x100000, 0x10fffd}
#endif
};
@@ -325,7 +327,8 @@ static const crange digitRangeTable[] = {
{0x11136, 0x1113f}, {0x111d0, 0x111d9}, {0x112f0, 0x112f9}, {0x11450, 0x11459},
{0x114d0, 0x114d9}, {0x11650, 0x11659}, {0x116c0, 0x116c9}, {0x11730, 0x11739},
{0x118e0, 0x118e9}, {0x11c50, 0x11c59}, {0x11d50, 0x11d59}, {0x11da0, 0x11da9},
{0x16a60, 0x16a69}, {0x16b50, 0x16b59}, {0x1d7ce, 0x1d7ff}, {0x1e950, 0x1e959}
{0x16a60, 0x16a69}, {0x16b50, 0x16b59}, {0x1d7ce, 0x1d7ff}, {0x1e140, 0x1e149},
{0x1e2f0, 0x1e2f9}, {0x1e950, 0x1e959}
#endif
};
@@ -348,7 +351,7 @@ static const crange punctRangeTable[] = {
{0x1b5a, 0x1b60}, {0x1bfc, 0x1bff}, {0x1c3b, 0x1c3f}, {0x1cc0, 0x1cc7},
{0x2010, 0x2027}, {0x2030, 0x2043}, {0x2045, 0x2051}, {0x2053, 0x205e},
{0x2308, 0x230b}, {0x2768, 0x2775}, {0x27e6, 0x27ef}, {0x2983, 0x2998},
{0x29d8, 0x29db}, {0x2cf9, 0x2cfc}, {0x2e00, 0x2e2e}, {0x2e30, 0x2e4e},
{0x29d8, 0x29db}, {0x2cf9, 0x2cfc}, {0x2e00, 0x2e2e}, {0x2e30, 0x2e4f},
{0x3001, 0x3003}, {0x3008, 0x3011}, {0x3014, 0x301f}, {0xa60d, 0xa60f},
{0xa6f2, 0xa6f7}, {0xa874, 0xa877}, {0xa8f8, 0xa8fa}, {0xa9c1, 0xa9cd},
{0xaa5c, 0xaa5f}, {0xfe10, 0xfe19}, {0xfe30, 0xfe52}, {0xfe54, 0xfe61},
@@ -372,8 +375,8 @@ static const chr punctCharTable[] = {
0xab, 0xb6, 0xb7, 0xbb, 0xbf, 0x37e, 0x387, 0x589, 0x58a,
0x5be, 0x5c0, 0x5c3, 0x5c6, 0x5f3, 0x5f4, 0x609, 0x60a, 0x60c,
0x60d, 0x61b, 0x61e, 0x61f, 0x6d4, 0x85e, 0x964, 0x965, 0x970,
0x9fd, 0xa76, 0xaf0, 0xc84, 0xdf4, 0xe4f, 0xe5a, 0xe5b, 0xf14,
0xf85, 0xfd9, 0xfda, 0x10fb, 0x1400, 0x166d, 0x166e, 0x169b, 0x169c,
0x9fd, 0xa76, 0xaf0, 0xc77, 0xc84, 0xdf4, 0xe4f, 0xe5a, 0xe5b,
0xf14, 0xf85, 0xfd9, 0xfda, 0x10fb, 0x1400, 0x166e, 0x169b, 0x169c,
0x1735, 0x1736, 0x1944, 0x1945, 0x1a1e, 0x1a1f, 0x1c7e, 0x1c7f, 0x1cd3,
0x207d, 0x207e, 0x208d, 0x208e, 0x2329, 0x232a, 0x27c5, 0x27c6, 0x29fc,
0x29fd, 0x2cfe, 0x2cff, 0x2d70, 0x3030, 0x303d, 0x30a0, 0x30fb, 0xa4fe,
@@ -384,8 +387,8 @@ static const chr punctCharTable[] = {
#if CHRBITS > 16
,0x1039f, 0x103d0, 0x1056f, 0x10857, 0x1091f, 0x1093f, 0x10a7f, 0x110bb, 0x110bc,
0x11174, 0x11175, 0x111cd, 0x111db, 0x112a9, 0x1145b, 0x1145d, 0x114c6, 0x1183b,
0x11c70, 0x11c71, 0x11ef7, 0x11ef8, 0x16a6e, 0x16a6f, 0x16af5, 0x16b44, 0x1bc9f,
0x1e95e, 0x1e95f
0x119e2, 0x11c70, 0x11c71, 0x11ef7, 0x11ef8, 0x11fff, 0x16a6e, 0x16a6f, 0x16af5,
0x16b44, 0x16fe2, 0x1bc9f, 0x1e95e, 0x1e95f
#endif
};
@@ -424,7 +427,7 @@ static const crange lowerRangeTable[] = {
{0x1f90, 0x1f97}, {0x1fa0, 0x1fa7}, {0x1fb0, 0x1fb4}, {0x1fc2, 0x1fc4},
{0x1fd0, 0x1fd3}, {0x1fe0, 0x1fe7}, {0x1ff2, 0x1ff4}, {0x2146, 0x2149},
{0x2c30, 0x2c5e}, {0x2c76, 0x2c7b}, {0x2d00, 0x2d25}, {0xa72f, 0xa731},
{0xa771, 0xa778}, {0xa793, 0xa795}, {0xab30, 0xab5a}, {0xab60, 0xab65},
{0xa771, 0xa778}, {0xa793, 0xa795}, {0xab30, 0xab5a}, {0xab60, 0xab67},
{0xab70, 0xabbf}, {0xfb00, 0xfb06}, {0xfb13, 0xfb17}, {0xff41, 0xff5a}
#if CHRBITS > 16
,{0x10428, 0x1044f}, {0x104d8, 0x104fb}, {0x10cc0, 0x10cf2}, {0x118c0, 0x118df},
@@ -504,7 +507,7 @@ static const chr lowerCharTable[] = {
0xa763, 0xa765, 0xa767, 0xa769, 0xa76b, 0xa76d, 0xa76f, 0xa77a, 0xa77c,
0xa77f, 0xa781, 0xa783, 0xa785, 0xa787, 0xa78c, 0xa78e, 0xa791, 0xa797,
0xa799, 0xa79b, 0xa79d, 0xa79f, 0xa7a1, 0xa7a3, 0xa7a5, 0xa7a7, 0xa7a9,
0xa7af, 0xa7b5, 0xa7b7, 0xa7b9, 0xa7fa
0xa7af, 0xa7b5, 0xa7b7, 0xa7b9, 0xa7bb, 0xa7bd, 0xa7bf, 0xa7c3, 0xa7fa
#if CHRBITS > 16
,0x1d4bb, 0x1d7cb
#endif
@@ -527,7 +530,7 @@ static const crange upperRangeTable[] = {
{0x1fe8, 0x1fec}, {0x1ff8, 0x1ffb}, {0x210b, 0x210d}, {0x2110, 0x2112},
{0x2119, 0x211d}, {0x212a, 0x212d}, {0x2130, 0x2133}, {0x2c00, 0x2c2e},
{0x2c62, 0x2c64}, {0x2c6d, 0x2c70}, {0x2c7e, 0x2c80}, {0xa7aa, 0xa7ae},
{0xa7b0, 0xa7b4}, {0xff21, 0xff3a}
{0xa7b0, 0xa7b4}, {0xa7c4, 0xa7c6}, {0xff21, 0xff3a}
#if CHRBITS > 16
,{0x10400, 0x10427}, {0x104b0, 0x104d3}, {0x10c80, 0x10cb2}, {0x118a0, 0x118bf},
{0x16e40, 0x16e5f}, {0x1d400, 0x1d419}, {0x1d434, 0x1d44d}, {0x1d468, 0x1d481},
@@ -606,7 +609,7 @@ static const chr upperCharTable[] = {
0xa768, 0xa76a, 0xa76c, 0xa76e, 0xa779, 0xa77b, 0xa77d, 0xa77e, 0xa780,
0xa782, 0xa784, 0xa786, 0xa78b, 0xa78d, 0xa790, 0xa792, 0xa796, 0xa798,
0xa79a, 0xa79c, 0xa79e, 0xa7a0, 0xa7a2, 0xa7a4, 0xa7a6, 0xa7a8, 0xa7b6,
0xa7b8
0xa7b8, 0xa7ba, 0xa7bc, 0xa7be, 0xa7c2
#if CHRBITS > 16
,0x1d49c, 0x1d49e, 0x1d49f, 0x1d4a2, 0x1d4a5, 0x1d4a6, 0x1d504, 0x1d505, 0x1d538,
0x1d539, 0x1d546, 0x1d7ca
@@ -640,61 +643,60 @@ static const crange graphRangeTable[] = {
{0xbae, 0xbb9}, {0xbbe, 0xbc2}, {0xbc6, 0xbc8}, {0xbca, 0xbcd},
{0xbe6, 0xbfa}, {0xc00, 0xc0c}, {0xc0e, 0xc10}, {0xc12, 0xc28},
{0xc2a, 0xc39}, {0xc3d, 0xc44}, {0xc46, 0xc48}, {0xc4a, 0xc4d},
{0xc58, 0xc5a}, {0xc60, 0xc63}, {0xc66, 0xc6f}, {0xc78, 0xc8c},
{0xc58, 0xc5a}, {0xc60, 0xc63}, {0xc66, 0xc6f}, {0xc77, 0xc8c},
{0xc8e, 0xc90}, {0xc92, 0xca8}, {0xcaa, 0xcb3}, {0xcb5, 0xcb9},
{0xcbc, 0xcc4}, {0xcc6, 0xcc8}, {0xcca, 0xccd}, {0xce0, 0xce3},
{0xce6, 0xcef}, {0xd00, 0xd03}, {0xd05, 0xd0c}, {0xd0e, 0xd10},
{0xd12, 0xd44}, {0xd46, 0xd48}, {0xd4a, 0xd4f}, {0xd54, 0xd63},
{0xd66, 0xd7f}, {0xd85, 0xd96}, {0xd9a, 0xdb1}, {0xdb3, 0xdbb},
{0xdc0, 0xdc6}, {0xdcf, 0xdd4}, {0xdd8, 0xddf}, {0xde6, 0xdef},
{0xdf2, 0xdf4}, {0xe01, 0xe3a}, {0xe3f, 0xe5b}, {0xe94, 0xe97},
{0xe99, 0xe9f}, {0xea1, 0xea3}, {0xead, 0xeb9}, {0xebb, 0xebd},
{0xec0, 0xec4}, {0xec8, 0xecd}, {0xed0, 0xed9}, {0xedc, 0xedf},
{0xf00, 0xf47}, {0xf49, 0xf6c}, {0xf71, 0xf97}, {0xf99, 0xfbc},
{0xfbe, 0xfcc}, {0xfce, 0xfda}, {0x1000, 0x10c5}, {0x10d0, 0x1248},
{0x124a, 0x124d}, {0x1250, 0x1256}, {0x125a, 0x125d}, {0x1260, 0x1288},
{0x128a, 0x128d}, {0x1290, 0x12b0}, {0x12b2, 0x12b5}, {0x12b8, 0x12be},
{0x12c2, 0x12c5}, {0x12c8, 0x12d6}, {0x12d8, 0x1310}, {0x1312, 0x1315},
{0x1318, 0x135a}, {0x135d, 0x137c}, {0x1380, 0x1399}, {0x13a0, 0x13f5},
{0x13f8, 0x13fd}, {0x1400, 0x167f}, {0x1681, 0x169c}, {0x16a0, 0x16f8},
{0x1700, 0x170c}, {0x170e, 0x1714}, {0x1720, 0x1736}, {0x1740, 0x1753},
{0x1760, 0x176c}, {0x176e, 0x1770}, {0x1780, 0x17dd}, {0x17e0, 0x17e9},
{0x17f0, 0x17f9}, {0x1800, 0x180d}, {0x1810, 0x1819}, {0x1820, 0x1878},
{0x1880, 0x18aa}, {0x18b0, 0x18f5}, {0x1900, 0x191e}, {0x1920, 0x192b},
{0x1930, 0x193b}, {0x1944, 0x196d}, {0x1970, 0x1974}, {0x1980, 0x19ab},
{0x19b0, 0x19c9}, {0x19d0, 0x19da}, {0x19de, 0x1a1b}, {0x1a1e, 0x1a5e},
{0x1a60, 0x1a7c}, {0x1a7f, 0x1a89}, {0x1a90, 0x1a99}, {0x1aa0, 0x1aad},
{0x1ab0, 0x1abe}, {0x1b00, 0x1b4b}, {0x1b50, 0x1b7c}, {0x1b80, 0x1bf3},
{0x1bfc, 0x1c37}, {0x1c3b, 0x1c49}, {0x1c4d, 0x1c88}, {0x1c90, 0x1cba},
{0x1cbd, 0x1cc7}, {0x1cd0, 0x1cf9}, {0x1d00, 0x1df9}, {0x1dfb, 0x1f15},
{0x1f18, 0x1f1d}, {0x1f20, 0x1f45}, {0x1f48, 0x1f4d}, {0x1f50, 0x1f57},
{0x1f5f, 0x1f7d}, {0x1f80, 0x1fb4}, {0x1fb6, 0x1fc4}, {0x1fc6, 0x1fd3},
{0x1fd6, 0x1fdb}, {0x1fdd, 0x1fef}, {0x1ff2, 0x1ff4}, {0x1ff6, 0x1ffe},
{0x2010, 0x2027}, {0x2030, 0x205e}, {0x2074, 0x208e}, {0x2090, 0x209c},
{0x20a0, 0x20bf}, {0x20d0, 0x20f0}, {0x2100, 0x218b}, {0x2190, 0x2426},
{0x2440, 0x244a}, {0x2460, 0x2b73}, {0x2b76, 0x2b95}, {0x2b98, 0x2bc8},
{0x2bca, 0x2bfe}, {0x2c00, 0x2c2e}, {0x2c30, 0x2c5e}, {0x2c60, 0x2cf3},
{0xdf2, 0xdf4}, {0xe01, 0xe3a}, {0xe3f, 0xe5b}, {0xe86, 0xe8a},
{0xe8c, 0xea3}, {0xea7, 0xebd}, {0xec0, 0xec4}, {0xec8, 0xecd},
{0xed0, 0xed9}, {0xedc, 0xedf}, {0xf00, 0xf47}, {0xf49, 0xf6c},
{0xf71, 0xf97}, {0xf99, 0xfbc}, {0xfbe, 0xfcc}, {0xfce, 0xfda},
{0x1000, 0x10c5}, {0x10d0, 0x1248}, {0x124a, 0x124d}, {0x1250, 0x1256},
{0x125a, 0x125d}, {0x1260, 0x1288}, {0x128a, 0x128d}, {0x1290, 0x12b0},
{0x12b2, 0x12b5}, {0x12b8, 0x12be}, {0x12c2, 0x12c5}, {0x12c8, 0x12d6},
{0x12d8, 0x1310}, {0x1312, 0x1315}, {0x1318, 0x135a}, {0x135d, 0x137c},
{0x1380, 0x1399}, {0x13a0, 0x13f5}, {0x13f8, 0x13fd}, {0x1400, 0x167f},
{0x1681, 0x169c}, {0x16a0, 0x16f8}, {0x1700, 0x170c}, {0x170e, 0x1714},
{0x1720, 0x1736}, {0x1740, 0x1753}, {0x1760, 0x176c}, {0x176e, 0x1770},
{0x1780, 0x17dd}, {0x17e0, 0x17e9}, {0x17f0, 0x17f9}, {0x1800, 0x180d},
{0x1810, 0x1819}, {0x1820, 0x1878}, {0x1880, 0x18aa}, {0x18b0, 0x18f5},
{0x1900, 0x191e}, {0x1920, 0x192b}, {0x1930, 0x193b}, {0x1944, 0x196d},
{0x1970, 0x1974}, {0x1980, 0x19ab}, {0x19b0, 0x19c9}, {0x19d0, 0x19da},
{0x19de, 0x1a1b}, {0x1a1e, 0x1a5e}, {0x1a60, 0x1a7c}, {0x1a7f, 0x1a89},
{0x1a90, 0x1a99}, {0x1aa0, 0x1aad}, {0x1ab0, 0x1abe}, {0x1b00, 0x1b4b},
{0x1b50, 0x1b7c}, {0x1b80, 0x1bf3}, {0x1bfc, 0x1c37}, {0x1c3b, 0x1c49},
{0x1c4d, 0x1c88}, {0x1c90, 0x1cba}, {0x1cbd, 0x1cc7}, {0x1cd0, 0x1cfa},
{0x1d00, 0x1df9}, {0x1dfb, 0x1f15}, {0x1f18, 0x1f1d}, {0x1f20, 0x1f45},
{0x1f48, 0x1f4d}, {0x1f50, 0x1f57}, {0x1f5f, 0x1f7d}, {0x1f80, 0x1fb4},
{0x1fb6, 0x1fc4}, {0x1fc6, 0x1fd3}, {0x1fd6, 0x1fdb}, {0x1fdd, 0x1fef},
{0x1ff2, 0x1ff4}, {0x1ff6, 0x1ffe}, {0x2010, 0x2027}, {0x2030, 0x205e},
{0x2074, 0x208e}, {0x2090, 0x209c}, {0x20a0, 0x20bf}, {0x20d0, 0x20f0},
{0x2100, 0x218b}, {0x2190, 0x2426}, {0x2440, 0x244a}, {0x2460, 0x2b73},
{0x2b76, 0x2b95}, {0x2b98, 0x2c2e}, {0x2c30, 0x2c5e}, {0x2c60, 0x2cf3},
{0x2cf9, 0x2d25}, {0x2d30, 0x2d67}, {0x2d7f, 0x2d96}, {0x2da0, 0x2da6},
{0x2da8, 0x2dae}, {0x2db0, 0x2db6}, {0x2db8, 0x2dbe}, {0x2dc0, 0x2dc6},
{0x2dc8, 0x2dce}, {0x2dd0, 0x2dd6}, {0x2dd8, 0x2dde}, {0x2de0, 0x2e4e},
{0x2dc8, 0x2dce}, {0x2dd0, 0x2dd6}, {0x2dd8, 0x2dde}, {0x2de0, 0x2e4f},
{0x2e80, 0x2e99}, {0x2e9b, 0x2ef3}, {0x2f00, 0x2fd5}, {0x2ff0, 0x2ffb},
{0x3001, 0x303f}, {0x3041, 0x3096}, {0x3099, 0x30ff}, {0x3105, 0x312f},
{0x3131, 0x318e}, {0x3190, 0x31ba}, {0x31c0, 0x31e3}, {0x31f0, 0x321e},
{0x3220, 0x32fe}, {0x3300, 0x4db5}, {0x4dc0, 0x9fef}, {0xa000, 0xa48c},
{0xa490, 0xa4c6}, {0xa4d0, 0xa62b}, {0xa640, 0xa6f7}, {0xa700, 0xa7b9},
{0xa7f7, 0xa82b}, {0xa830, 0xa839}, {0xa840, 0xa877}, {0xa880, 0xa8c5},
{0xa8ce, 0xa8d9}, {0xa8e0, 0xa953}, {0xa95f, 0xa97c}, {0xa980, 0xa9cd},
{0xa9cf, 0xa9d9}, {0xa9de, 0xa9fe}, {0xaa00, 0xaa36}, {0xaa40, 0xaa4d},
{0xaa50, 0xaa59}, {0xaa5c, 0xaac2}, {0xaadb, 0xaaf6}, {0xab01, 0xab06},
{0xab09, 0xab0e}, {0xab11, 0xab16}, {0xab20, 0xab26}, {0xab28, 0xab2e},
{0xab30, 0xab65}, {0xab70, 0xabed}, {0xabf0, 0xabf9}, {0xac00, 0xd7a3},
{0xd7b0, 0xd7c6}, {0xd7cb, 0xd7fb}, {0xf900, 0xfa6d}, {0xfa70, 0xfad9},
{0xfb00, 0xfb06}, {0xfb13, 0xfb17}, {0xfb1d, 0xfb36}, {0xfb38, 0xfb3c},
{0xfb46, 0xfbc1}, {0xfbd3, 0xfd3f}, {0xfd50, 0xfd8f}, {0xfd92, 0xfdc7},
{0xfdf0, 0xfdfd}, {0xfe00, 0xfe19}, {0xfe20, 0xfe52}, {0xfe54, 0xfe66},
{0xfe68, 0xfe6b}, {0xfe70, 0xfe74}, {0xfe76, 0xfefc}, {0xff01, 0xffbe},
{0xffc2, 0xffc7}, {0xffca, 0xffcf}, {0xffd2, 0xffd7}, {0xffda, 0xffdc},
{0xffe0, 0xffe6}, {0xffe8, 0xffee}
{0xa490, 0xa4c6}, {0xa4d0, 0xa62b}, {0xa640, 0xa6f7}, {0xa700, 0xa7bf},
{0xa7c2, 0xa7c6}, {0xa7f7, 0xa82b}, {0xa830, 0xa839}, {0xa840, 0xa877},
{0xa880, 0xa8c5}, {0xa8ce, 0xa8d9}, {0xa8e0, 0xa953}, {0xa95f, 0xa97c},
{0xa980, 0xa9cd}, {0xa9cf, 0xa9d9}, {0xa9de, 0xa9fe}, {0xaa00, 0xaa36},
{0xaa40, 0xaa4d}, {0xaa50, 0xaa59}, {0xaa5c, 0xaac2}, {0xaadb, 0xaaf6},
{0xab01, 0xab06}, {0xab09, 0xab0e}, {0xab11, 0xab16}, {0xab20, 0xab26},
{0xab28, 0xab2e}, {0xab30, 0xab67}, {0xab70, 0xabed}, {0xabf0, 0xabf9},
{0xac00, 0xd7a3}, {0xd7b0, 0xd7c6}, {0xd7cb, 0xd7fb}, {0xf900, 0xfa6d},
{0xfa70, 0xfad9}, {0xfb00, 0xfb06}, {0xfb13, 0xfb17}, {0xfb1d, 0xfb36},
{0xfb38, 0xfb3c}, {0xfb46, 0xfbc1}, {0xfbd3, 0xfd3f}, {0xfd50, 0xfd8f},
{0xfd92, 0xfdc7}, {0xfdf0, 0xfdfd}, {0xfe00, 0xfe19}, {0xfe20, 0xfe52},
{0xfe54, 0xfe66}, {0xfe68, 0xfe6b}, {0xfe70, 0xfe74}, {0xfe76, 0xfefc},
{0xff01, 0xffbe}, {0xffc2, 0xffc7}, {0xffca, 0xffcf}, {0xffd2, 0xffd7},
{0xffda, 0xffdc}, {0xffe0, 0xffe6}, {0xffe8, 0xffee}
#if CHRBITS > 16
,{0x10000, 0x1000b}, {0x1000d, 0x10026}, {0x10028, 0x1003a}, {0x1003f, 0x1004d},
{0x10050, 0x1005d}, {0x10080, 0x100fa}, {0x10100, 0x10102}, {0x10107, 0x10133},
@@ -711,29 +713,31 @@ static const crange graphRangeTable[] = {
{0x10aeb, 0x10af6}, {0x10b00, 0x10b35}, {0x10b39, 0x10b55}, {0x10b58, 0x10b72},
{0x10b78, 0x10b91}, {0x10b99, 0x10b9c}, {0x10ba9, 0x10baf}, {0x10c00, 0x10c48},
{0x10c80, 0x10cb2}, {0x10cc0, 0x10cf2}, {0x10cfa, 0x10d27}, {0x10d30, 0x10d39},
{0x10e60, 0x10e7e}, {0x10f00, 0x10f27}, {0x10f30, 0x10f59}, {0x11000, 0x1104d},
{0x11052, 0x1106f}, {0x1107f, 0x110bc}, {0x110be, 0x110c1}, {0x110d0, 0x110e8},
{0x110f0, 0x110f9}, {0x11100, 0x11134}, {0x11136, 0x11146}, {0x11150, 0x11176},
{0x11180, 0x111cd}, {0x111d0, 0x111df}, {0x111e1, 0x111f4}, {0x11200, 0x11211},
{0x11213, 0x1123e}, {0x11280, 0x11286}, {0x1128a, 0x1128d}, {0x1128f, 0x1129d},
{0x1129f, 0x112a9}, {0x112b0, 0x112ea}, {0x112f0, 0x112f9}, {0x11300, 0x11303},
{0x11305, 0x1130c}, {0x11313, 0x11328}, {0x1132a, 0x11330}, {0x11335, 0x11339},
{0x1133b, 0x11344}, {0x1134b, 0x1134d}, {0x1135d, 0x11363}, {0x11366, 0x1136c},
{0x11370, 0x11374}, {0x11400, 0x11459}, {0x11480, 0x114c7}, {0x114d0, 0x114d9},
{0x11580, 0x115b5}, {0x115b8, 0x115dd}, {0x11600, 0x11644}, {0x11650, 0x11659},
{0x11660, 0x1166c}, {0x11680, 0x116b7}, {0x116c0, 0x116c9}, {0x11700, 0x1171a},
{0x1171d, 0x1172b}, {0x11730, 0x1173f}, {0x11800, 0x1183b}, {0x118a0, 0x118f2},
{0x11a00, 0x11a47}, {0x11a50, 0x11a83}, {0x11a86, 0x11aa2}, {0x11ac0, 0x11af8},
{0x10e60, 0x10e7e}, {0x10f00, 0x10f27}, {0x10f30, 0x10f59}, {0x10fe0, 0x10ff6},
{0x11000, 0x1104d}, {0x11052, 0x1106f}, {0x1107f, 0x110bc}, {0x110be, 0x110c1},
{0x110d0, 0x110e8}, {0x110f0, 0x110f9}, {0x11100, 0x11134}, {0x11136, 0x11146},
{0x11150, 0x11176}, {0x11180, 0x111cd}, {0x111d0, 0x111df}, {0x111e1, 0x111f4},
{0x11200, 0x11211}, {0x11213, 0x1123e}, {0x11280, 0x11286}, {0x1128a, 0x1128d},
{0x1128f, 0x1129d}, {0x1129f, 0x112a9}, {0x112b0, 0x112ea}, {0x112f0, 0x112f9},
{0x11300, 0x11303}, {0x11305, 0x1130c}, {0x11313, 0x11328}, {0x1132a, 0x11330},
{0x11335, 0x11339}, {0x1133b, 0x11344}, {0x1134b, 0x1134d}, {0x1135d, 0x11363},
{0x11366, 0x1136c}, {0x11370, 0x11374}, {0x11400, 0x11459}, {0x1145d, 0x1145f},
{0x11480, 0x114c7}, {0x114d0, 0x114d9}, {0x11580, 0x115b5}, {0x115b8, 0x115dd},
{0x11600, 0x11644}, {0x11650, 0x11659}, {0x11660, 0x1166c}, {0x11680, 0x116b8},
{0x116c0, 0x116c9}, {0x11700, 0x1171a}, {0x1171d, 0x1172b}, {0x11730, 0x1173f},
{0x11800, 0x1183b}, {0x118a0, 0x118f2}, {0x119a0, 0x119a7}, {0x119aa, 0x119d7},
{0x119da, 0x119e4}, {0x11a00, 0x11a47}, {0x11a50, 0x11aa2}, {0x11ac0, 0x11af8},
{0x11c00, 0x11c08}, {0x11c0a, 0x11c36}, {0x11c38, 0x11c45}, {0x11c50, 0x11c6c},
{0x11c70, 0x11c8f}, {0x11c92, 0x11ca7}, {0x11ca9, 0x11cb6}, {0x11d00, 0x11d06},
{0x11d0b, 0x11d36}, {0x11d3f, 0x11d47}, {0x11d50, 0x11d59}, {0x11d60, 0x11d65},
{0x11d6a, 0x11d8e}, {0x11d93, 0x11d98}, {0x11da0, 0x11da9}, {0x11ee0, 0x11ef8},
{0x12000, 0x12399}, {0x12400, 0x1246e}, {0x12470, 0x12474}, {0x12480, 0x12543},
{0x13000, 0x1342e}, {0x14400, 0x14646}, {0x16800, 0x16a38}, {0x16a40, 0x16a5e},
{0x16a60, 0x16a69}, {0x16ad0, 0x16aed}, {0x16af0, 0x16af5}, {0x16b00, 0x16b45},
{0x16b50, 0x16b59}, {0x16b5b, 0x16b61}, {0x16b63, 0x16b77}, {0x16b7d, 0x16b8f},
{0x16e40, 0x16e9a}, {0x16f00, 0x16f44}, {0x16f50, 0x16f7e}, {0x16f8f, 0x16f9f},
{0x17000, 0x187f1}, {0x18800, 0x18af2}, {0x1b000, 0x1b11e}, {0x1b170, 0x1b2fb},
{0x11fc0, 0x11ff1}, {0x11fff, 0x12399}, {0x12400, 0x1246e}, {0x12470, 0x12474},
{0x12480, 0x12543}, {0x13000, 0x1342e}, {0x14400, 0x14646}, {0x16800, 0x16a38},
{0x16a40, 0x16a5e}, {0x16a60, 0x16a69}, {0x16ad0, 0x16aed}, {0x16af0, 0x16af5},
{0x16b00, 0x16b45}, {0x16b50, 0x16b59}, {0x16b5b, 0x16b61}, {0x16b63, 0x16b77},
{0x16b7d, 0x16b8f}, {0x16e40, 0x16e9a}, {0x16f00, 0x16f4a}, {0x16f4f, 0x16f87},
{0x16f8f, 0x16f9f}, {0x16fe0, 0x16fe3}, {0x17000, 0x187f7}, {0x18800, 0x18af2},
{0x1b000, 0x1b11e}, {0x1b150, 0x1b152}, {0x1b164, 0x1b167}, {0x1b170, 0x1b2fb},
{0x1bc00, 0x1bc6a}, {0x1bc70, 0x1bc7c}, {0x1bc80, 0x1bc88}, {0x1bc90, 0x1bc99},
{0x1bc9c, 0x1bc9f}, {0x1d000, 0x1d0f5}, {0x1d100, 0x1d126}, {0x1d129, 0x1d172},
{0x1d17b, 0x1d1e8}, {0x1d200, 0x1d245}, {0x1d2e0, 0x1d2f3}, {0x1d300, 0x1d356},
@@ -742,22 +746,24 @@ static const crange graphRangeTable[] = {
{0x1d50d, 0x1d514}, {0x1d516, 0x1d51c}, {0x1d51e, 0x1d539}, {0x1d53b, 0x1d53e},
{0x1d540, 0x1d544}, {0x1d54a, 0x1d550}, {0x1d552, 0x1d6a5}, {0x1d6a8, 0x1d7cb},
{0x1d7ce, 0x1da8b}, {0x1da9b, 0x1da9f}, {0x1daa1, 0x1daaf}, {0x1e000, 0x1e006},
{0x1e008, 0x1e018}, {0x1e01b, 0x1e021}, {0x1e026, 0x1e02a}, {0x1e800, 0x1e8c4},
{0x1e8c7, 0x1e8d6}, {0x1e900, 0x1e94a}, {0x1e950, 0x1e959}, {0x1ec71, 0x1ecb4},
{0x1ee00, 0x1ee03}, {0x1ee05, 0x1ee1f}, {0x1ee29, 0x1ee32}, {0x1ee34, 0x1ee37},
{0x1ee4d, 0x1ee4f}, {0x1ee67, 0x1ee6a}, {0x1ee6c, 0x1ee72}, {0x1ee74, 0x1ee77},
{0x1ee79, 0x1ee7c}, {0x1ee80, 0x1ee89}, {0x1ee8b, 0x1ee9b}, {0x1eea1, 0x1eea3},
{0x1eea5, 0x1eea9}, {0x1eeab, 0x1eebb}, {0x1f000, 0x1f02b}, {0x1f030, 0x1f093},
{0x1f0a0, 0x1f0ae}, {0x1f0b1, 0x1f0bf}, {0x1f0c1, 0x1f0cf}, {0x1f0d1, 0x1f0f5},
{0x1f100, 0x1f10c}, {0x1f110, 0x1f16b}, {0x1f170, 0x1f1ac}, {0x1f1e6, 0x1f202},
{0x1f210, 0x1f23b}, {0x1f240, 0x1f248}, {0x1f260, 0x1f265}, {0x1f300, 0x1f6d4},
{0x1f6e0, 0x1f6ec}, {0x1f6f0, 0x1f6f9}, {0x1f700, 0x1f773}, {0x1f780, 0x1f7d8},
{0x1f800, 0x1f80b}, {0x1f810, 0x1f847}, {0x1f850, 0x1f859}, {0x1f860, 0x1f887},
{0x1f890, 0x1f8ad}, {0x1f900, 0x1f90b}, {0x1f910, 0x1f93e}, {0x1f940, 0x1f970},
{0x1f973, 0x1f976}, {0x1f97c, 0x1f9a2}, {0x1f9b0, 0x1f9b9}, {0x1f9c0, 0x1f9c2},
{0x1f9d0, 0x1f9ff}, {0x1fa60, 0x1fa6d}, {0x20000, 0x2a6d6}, {0x2a700, 0x2b734},
{0x2b740, 0x2b81d}, {0x2b820, 0x2cea1}, {0x2ceb0, 0x2ebe0}, {0x2f800, 0x2fa1d},
{0xe0100, 0xe01ef}
{0x1e008, 0x1e018}, {0x1e01b, 0x1e021}, {0x1e026, 0x1e02a}, {0x1e100, 0x1e12c},
{0x1e130, 0x1e13d}, {0x1e140, 0x1e149}, {0x1e2c0, 0x1e2f9}, {0x1e800, 0x1e8c4},
{0x1e8c7, 0x1e8d6}, {0x1e900, 0x1e94b}, {0x1e950, 0x1e959}, {0x1ec71, 0x1ecb4},
{0x1ed01, 0x1ed3d}, {0x1ee00, 0x1ee03}, {0x1ee05, 0x1ee1f}, {0x1ee29, 0x1ee32},
{0x1ee34, 0x1ee37}, {0x1ee4d, 0x1ee4f}, {0x1ee67, 0x1ee6a}, {0x1ee6c, 0x1ee72},
{0x1ee74, 0x1ee77}, {0x1ee79, 0x1ee7c}, {0x1ee80, 0x1ee89}, {0x1ee8b, 0x1ee9b},
{0x1eea1, 0x1eea3}, {0x1eea5, 0x1eea9}, {0x1eeab, 0x1eebb}, {0x1f000, 0x1f02b},
{0x1f030, 0x1f093}, {0x1f0a0, 0x1f0ae}, {0x1f0b1, 0x1f0bf}, {0x1f0c1, 0x1f0cf},
{0x1f0d1, 0x1f0f5}, {0x1f100, 0x1f10c}, {0x1f110, 0x1f16c}, {0x1f170, 0x1f1ac},
{0x1f1e6, 0x1f202}, {0x1f210, 0x1f23b}, {0x1f240, 0x1f248}, {0x1f260, 0x1f265},
{0x1f300, 0x1f6d5}, {0x1f6e0, 0x1f6ec}, {0x1f6f0, 0x1f6fa}, {0x1f700, 0x1f773},
{0x1f780, 0x1f7d8}, {0x1f7e0, 0x1f7eb}, {0x1f800, 0x1f80b}, {0x1f810, 0x1f847},
{0x1f850, 0x1f859}, {0x1f860, 0x1f887}, {0x1f890, 0x1f8ad}, {0x1f900, 0x1f90b},
{0x1f90d, 0x1f971}, {0x1f973, 0x1f976}, {0x1f97a, 0x1f9a2}, {0x1f9a5, 0x1f9aa},
{0x1f9ae, 0x1f9ca}, {0x1f9cd, 0x1fa53}, {0x1fa60, 0x1fa6d}, {0x1fa70, 0x1fa73},
{0x1fa78, 0x1fa7a}, {0x1fa80, 0x1fa82}, {0x1fa90, 0x1fa95}, {0x20000, 0x2a6d6},
{0x2a700, 0x2b734}, {0x2b740, 0x2b81d}, {0x2b820, 0x2cea1}, {0x2ceb0, 0x2ebe0},
{0x2f800, 0x2fa1d}, {0xe0100, 0xe01ef}
#endif
};
@@ -770,21 +776,20 @@ static const chr graphCharTable[] = {
0xb10, 0xb32, 0xb33, 0xb47, 0xb48, 0xb56, 0xb57, 0xb5c, 0xb5d,
0xb82, 0xb83, 0xb99, 0xb9a, 0xb9c, 0xb9e, 0xb9f, 0xba3, 0xba4,
0xbd0, 0xbd7, 0xc55, 0xc56, 0xcd5, 0xcd6, 0xcde, 0xcf1, 0xcf2,
0xd82, 0xd83, 0xdbd, 0xdca, 0xdd6, 0xe81, 0xe82, 0xe84, 0xe87,
0xe88, 0xe8a, 0xe8d, 0xea5, 0xea7, 0xeaa, 0xeab, 0xec6, 0x10c7,
0x10cd, 0x1258, 0x12c0, 0x1772, 0x1773, 0x1940, 0x1f59, 0x1f5b, 0x1f5d,
0x2070, 0x2071, 0x2d27, 0x2d2d, 0x2d6f, 0x2d70, 0xfb3e, 0xfb40, 0xfb41,
0xfb43, 0xfb44, 0xfffc, 0xfffd
0xd82, 0xd83, 0xdbd, 0xdca, 0xdd6, 0xe81, 0xe82, 0xe84, 0xea5,
0xec6, 0x10c7, 0x10cd, 0x1258, 0x12c0, 0x1772, 0x1773, 0x1940, 0x1f59,
0x1f5b, 0x1f5d, 0x2070, 0x2071, 0x2d27, 0x2d2d, 0x2d6f, 0x2d70, 0xfb3e,
0xfb40, 0xfb41, 0xfb43, 0xfb44, 0xfffc, 0xfffd
#if CHRBITS > 16
,0x1003c, 0x1003d, 0x101a0, 0x1056f, 0x10808, 0x10837, 0x10838, 0x1083c, 0x108f4,
0x108f5, 0x1093f, 0x10a05, 0x10a06, 0x11288, 0x1130f, 0x11310, 0x11332, 0x11333,
0x11347, 0x11348, 0x11350, 0x11357, 0x1145b, 0x1145d, 0x1145e, 0x118ff, 0x11d08,
0x11d09, 0x11d3a, 0x11d3c, 0x11d3d, 0x11d67, 0x11d68, 0x11d90, 0x11d91, 0x16a6e,
0x16a6f, 0x16fe0, 0x16fe1, 0x1d49e, 0x1d49f, 0x1d4a2, 0x1d4a5, 0x1d4a6, 0x1d4bb,
0x1d546, 0x1e023, 0x1e024, 0x1e95e, 0x1e95f, 0x1ee21, 0x1ee22, 0x1ee24, 0x1ee27,
0x1ee39, 0x1ee3b, 0x1ee42, 0x1ee47, 0x1ee49, 0x1ee4b, 0x1ee51, 0x1ee52, 0x1ee54,
0x1ee57, 0x1ee59, 0x1ee5b, 0x1ee5d, 0x1ee5f, 0x1ee61, 0x1ee62, 0x1ee64, 0x1ee7e,
0x1eef0, 0x1eef1, 0x1f250, 0x1f251, 0x1f97a
0x11347, 0x11348, 0x11350, 0x11357, 0x1145b, 0x118ff, 0x11d08, 0x11d09, 0x11d3a,
0x11d3c, 0x11d3d, 0x11d67, 0x11d68, 0x11d90, 0x11d91, 0x16a6e, 0x16a6f, 0x1d49e,
0x1d49f, 0x1d4a2, 0x1d4a5, 0x1d4a6, 0x1d4bb, 0x1d546, 0x1e023, 0x1e024, 0x1e14e,
0x1e14f, 0x1e2ff, 0x1e95e, 0x1e95f, 0x1ee21, 0x1ee22, 0x1ee24, 0x1ee27, 0x1ee39,
0x1ee3b, 0x1ee42, 0x1ee47, 0x1ee49, 0x1ee4b, 0x1ee51, 0x1ee52, 0x1ee54, 0x1ee57,
0x1ee59, 0x1ee5b, 0x1ee5d, 0x1ee5f, 0x1ee61, 0x1ee62, 0x1ee64, 0x1ee7e, 0x1eef0,
0x1eef1, 0x1f250, 0x1f251
#endif
};
+18 -11
View File
@@ -1211,7 +1211,7 @@ BinaryFormatCmd(
badField:
{
Tcl_UniChar ch = 0;
char buf[TCL_UTF_MAX + 1];
char buf[TCL_UTF_MAX + 1] = "";
TclUtfToUniChar(errorString, &ch);
buf[Tcl_UniCharToUtf(ch, buf)] = '\0';
@@ -1581,7 +1581,7 @@ BinaryScanCmd(
badField:
{
Tcl_UniChar ch = 0;
char buf[TCL_UTF_MAX + 1];
char buf[TCL_UTF_MAX + 1] = "";
TclUtfToUniChar(errorString, &ch);
buf[Tcl_UniCharToUtf(ch, buf)] = '\0';
@@ -2395,7 +2395,7 @@ BinaryDecodeHex(
c = *data++;
if (!isxdigit((int) c)) {
if (strict || !isspace(c)) {
if (strict || !TclIsSpaceProc(c)) {
goto badChar;
}
i--;
@@ -2742,7 +2742,7 @@ BinaryDecodeUu(
if (lineLen < 0) {
c = *data++;
if (c < 32 || c > 96) {
if (strict || !isspace(c)) {
if (strict || !TclIsSpaceProc(c)) {
goto badUu;
}
i--;
@@ -2760,7 +2760,7 @@ BinaryDecodeUu(
d[i] = c = *data++;
if (c < 32 || c > 96) {
if (strict) {
if (!isspace(c)) {
if (!TclIsSpaceProc(c)) {
goto badUu;
} else if (c == '\n') {
goto shortUu;
@@ -2804,7 +2804,7 @@ BinaryDecodeUu(
} else if (c >= 32 && c <= 96) {
data--;
break;
} else if (strict || !isspace(c)) {
} else if (strict || !TclIsSpaceProc(c)) {
goto badUu;
}
} while (data < dataend);
@@ -2914,6 +2914,11 @@ BinaryDecode64(
} else if (i > 1) {
c = '=';
} else {
if (strict && i <= 1) {
/* single resp. unfulfilled char (each 4th next single char)
* is rather bad64 error case in strict mode */
goto bad64;
}
cut += 3;
break;
}
@@ -2929,7 +2934,7 @@ BinaryDecode64(
if (c == '=' && i > 1) {
value <<= 6;
cut++;
} else if (!strict && isspace(c)) {
} else if (!strict && TclIsSpaceProc(c)) {
i--;
} else {
goto bad64;
@@ -2944,10 +2949,12 @@ BinaryDecode64(
value = (value << 6) | 0x3e;
} else if (c == '/') {
value = (value << 6) | 0x3f;
} else if (c == '=') {
} else if (c == '=' && (
!strict || i > 1) /* "=" and "a=" is rather bad64 error case in strict mode */
) {
value <<= 6;
cut++;
} else if (strict || !isspace(c)) {
if (i) cut++;
} else if (strict || !TclIsSpaceProc(c)) {
goto bad64;
} else {
i--;
@@ -2968,7 +2975,7 @@ BinaryDecode64(
goto bad64;
}
for (; data < dataend; data++) {
if (!isspace(*data)) {
if (!TclIsSpaceProc(*data)) {
goto bad64;
}
}
+1 -1
View File
@@ -2127,7 +2127,7 @@ PathJoinCmd(
Tcl_WrongNumArgs(interp, 1, objv, "name ?name ...?");
return TCL_ERROR;
}
Tcl_SetObjResult(interp, TclJoinPath(objc - 1, objv + 1));
Tcl_SetObjResult(interp, TclJoinPath(objc - 1, objv + 1, 0));
return TCL_OK;
}
+178 -158
View File
@@ -1080,13 +1080,13 @@ Tcl_SplitObjCmd(
Tcl_InitHashTable(&charReuseTable, TCL_ONE_WORD_KEYS);
for ( ; stringPtr < end; stringPtr += len) {
int fullchar;
int fullchar;
len = TclUtfToUniChar(stringPtr, &ch);
fullchar = ch;
#if TCL_UTF_MAX == 4
if (!len) {
len += TclUtfToUniChar(stringPtr, &ch);
if ((ch >= 0xD800) && (len < 3)) {
len += TclUtfToUniChar(stringPtr + len, &ch);
fullchar = (((fullchar & 0x3ff) << 10) | (ch & 0x3ff)) + 0x10000;
}
#endif
@@ -1425,9 +1425,14 @@ StringIndexCmd(
Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(&uch, 1));
} else {
char buf[TCL_UTF_MAX];
char buf[TCL_UTF_MAX] = "";
length = Tcl_UniCharToUtf(ch, buf);
#if TCL_UTF_MAX > 3
if ((ch >= 0xD800) && (length < 3)) {
length += Tcl_UniCharToUtf(-1, buf + length);
}
#endif
Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, length));
}
}
@@ -1795,8 +1800,8 @@ StringIsCmd(
length2 = TclUtfToUniChar(string1, &ch);
fullchar = ch;
#if TCL_UTF_MAX == 4
if (!length2) {
length2 = TclUtfToUniChar(string1, &ch);
if ((ch >= 0xD800) && (length2 < 3)) {
length2 += TclUtfToUniChar(string1 + length2, &ch);
fullchar = (((fullchar & 0x3ff) << 10) | (ch & 0x3ff)) + 0x10000;
}
#endif
@@ -1876,7 +1881,7 @@ StringMapCmd(
const char *string = TclGetStringFromObj(objv[1], &length2);
if ((length2 > 1) &&
strncmp(string, "-nocase", (size_t) length2) == 0) {
strncmp(string, "-nocase", length2) == 0) {
nocase = 1;
} else {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
@@ -2143,7 +2148,7 @@ StringMatchCmd(
const char *string = TclGetStringFromObj(objv[1], &length);
if ((length > 1) &&
strncmp(string, "-nocase", (size_t) length) == 0) {
strncmp(string, "-nocase", length) == 0) {
nocase = TCL_MATCH_NOCASE;
} else {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
@@ -2611,10 +2616,10 @@ StringEqualCmd(
for (i = 1; i < objc-2; i++) {
string2 = TclGetStringFromObj(objv[i], &length2);
if ((length2 > 1) && !strncmp(string2, "-nocase", (size_t)length2)) {
if ((length2 > 1) && !strncmp(string2, "-nocase", length2)) {
nocase = 1;
} else if ((length2 > 1)
&& !strncmp(string2, "-length", (size_t)length2)) {
&& !strncmp(string2, "-length", length2)) {
if (i+1 >= objc-2) {
goto str_cmp_args;
}
@@ -2638,9 +2643,7 @@ StringEqualCmd(
*/
objv += objc-2;
match = TclStringCmp (objv[0], objv[1], 0, nocase, reqlength);
match = TclStringCmp(objv[0], objv[1], 0, nocase, reqlength);
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(match ? 0 : 1));
return TCL_OK;
}
@@ -2678,186 +2681,203 @@ StringCmpCmd(
int match, nocase, reqlength, status;
if ((status = TclStringCmpOpts(interp, objc, objv, &nocase, &reqlength))
!= TCL_OK) {
status = TclStringCmpOpts(interp, objc, objv, &nocase, &reqlength);
if (status != TCL_OK) {
return status;
}
objv += objc-2;
match = TclStringCmp (objv[0], objv[1], 0, nocase, reqlength);
match = TclStringCmp(objv[0], objv[1], 0, nocase, reqlength);
Tcl_SetObjResult(interp, Tcl_NewIntObj(match));
return TCL_OK;
}
int TclStringCmp (
Tcl_Obj *value1Ptr,
Tcl_Obj *value2Ptr,
int checkEq, /* comparison is only for equality */
int nocase, /* comparison is not case sensitive */
int reqlength /* requested length */
) {
/*
*----------------------------------------------------------------------
*
* TclStringCmp --
*
* This is the core of Tcl's string comparison. It only handles byte
* arrays, UNICODE strings and UTF-8 strings correctly.
*
* Results:
* -1 if value1Ptr is less than value2Ptr, 0 if they are equal, or 1 if
* value1Ptr is greater.
*
* Side effects:
* May cause string representations of objects to be allocated.
*
*----------------------------------------------------------------------
*/
int
TclStringCmp(
Tcl_Obj *value1Ptr,
Tcl_Obj *value2Ptr,
int checkEq, /* comparison is only for equality */
int nocase, /* comparison is not case sensitive */
int reqlength) /* requested length; -1 to compare whole
* strings */
{
char *s1, *s2;
int empty, length, match, s1len, s2len;
memCmpFn_t memCmpFn;
if ((reqlength == 0) || (value1Ptr == value2Ptr)) {
/*
* Always match at 0 chars of if it is the same obj.
* Always match at 0 chars or if it is the same obj.
*/
match = 0;
} else {
return 0;
}
if (!nocase && TclIsPureByteArray(value1Ptr)
&& TclIsPureByteArray(value2Ptr)) {
/*
* Use binary versions of comparisons since that won't cause undue
* type conversions and it is much faster. Only do this if we're
* case-sensitive (which is all that really makes sense with byte
* arrays anyway, and we have no memcasecmp() for some reason... :^)
*/
s1 = (char *) Tcl_GetByteArrayFromObj(value1Ptr, &s1len);
s2 = (char *) Tcl_GetByteArrayFromObj(value2Ptr, &s2len);
memCmpFn = memcmp;
} else if ((value1Ptr->typePtr == &tclStringType)
&& (value2Ptr->typePtr == &tclStringType)) {
/*
* Do a unicode-specific comparison if both of the args are of
* String type. If the char length == byte length, we can do a
* memcmp. In benchmark testing this proved the most efficient
* check between the unicode and string comparison operations.
*/
if (!nocase && TclIsPureByteArray(value1Ptr)
&& TclIsPureByteArray(value2Ptr)) {
/*
* Use binary versions of comparisons since that won't cause undue
* type conversions and it is much faster. Only do this if we're
* case-sensitive (which is all that really makes sense with byte
* arrays anyway, and we have no memcasecmp() for some reason... :^)
*/
if (nocase) {
s1 = (char *) Tcl_GetUnicodeFromObj(value1Ptr, &s1len);
s2 = (char *) Tcl_GetUnicodeFromObj(value2Ptr, &s2len);
memCmpFn = (memCmpFn_t)Tcl_UniCharNcasecmp;
s1 = (char *) Tcl_GetByteArrayFromObj(value1Ptr, &s1len);
s2 = (char *) Tcl_GetByteArrayFromObj(value2Ptr, &s2len);
memCmpFn = memcmp;
} else if ((value1Ptr->typePtr == &tclStringType)
&& (value2Ptr->typePtr == &tclStringType)) {
/*
* Do a unicode-specific comparison if both of the args are of String
* type. If the char length == byte length, we can do a memcmp. In
* benchmark testing this proved the most efficient check between the
* unicode and string comparison operations.
*/
if (nocase) {
s1 = (char *) Tcl_GetUnicodeFromObj(value1Ptr, &s1len);
s2 = (char *) Tcl_GetUnicodeFromObj(value2Ptr, &s2len);
memCmpFn = (memCmpFn_t)Tcl_UniCharNcasecmp;
} else {
s1len = Tcl_GetCharLength(value1Ptr);
s2len = Tcl_GetCharLength(value2Ptr);
if ((s1len == value1Ptr->length)
&& (value1Ptr->bytes != NULL)
&& (s2len == value2Ptr->length)
&& (value2Ptr->bytes != NULL)) {
s1 = value1Ptr->bytes;
s2 = value2Ptr->bytes;
memCmpFn = memcmp;
} else {
s1len = Tcl_GetCharLength(value1Ptr);
s2len = Tcl_GetCharLength(value2Ptr);
if ((s1len == value1Ptr->length)
&& (value1Ptr->bytes != NULL)
&& (s2len == value2Ptr->length)
&& (value2Ptr->bytes != NULL)) {
s1 = value1Ptr->bytes;
s2 = value2Ptr->bytes;
memCmpFn = memcmp;
} else {
s1 = (char *) Tcl_GetUnicode(value1Ptr);
s2 = (char *) Tcl_GetUnicode(value2Ptr);
if (
s1 = (char *) Tcl_GetUnicode(value1Ptr);
s2 = (char *) Tcl_GetUnicode(value2Ptr);
if (
#ifdef WORDS_BIGENDIAN
1
#else
checkEq
#endif
) {
memCmpFn = memcmp;
s1len *= sizeof(Tcl_UniChar);
s2len *= sizeof(Tcl_UniChar);
} else {
memCmpFn = (memCmpFn_t) Tcl_UniCharNcmp;
}
#endif /* WORDS_BIGENDIAN */
) {
memCmpFn = memcmp;
s1len *= sizeof(Tcl_UniChar);
s2len *= sizeof(Tcl_UniChar);
} else {
memCmpFn = (memCmpFn_t) Tcl_UniCharNcmp;
}
}
}
} else {
/*
* Get the string representations, being careful in case we have
* special empty string objects about.
*/
empty = TclCheckEmptyString(value1Ptr);
if (empty > 0) {
switch (TclCheckEmptyString(value2Ptr)) {
case -1:
s1 = "";
s1len = 0;
s2 = TclGetStringFromObj(value2Ptr, &s2len);
break;
case 0:
return -1;
default: /* avoid warn: `s2` may be used uninitialized */
return 0;
}
} else if (TclCheckEmptyString(value2Ptr) > 0) {
switch (empty) {
case -1:
s2 = "";
s2len = 0;
s1 = TclGetStringFromObj(value1Ptr, &s1len);
break;
case 0:
return 1;
default: /* avoid warn: `s1` may be used uninitialized */
return 0;
}
} else {
if ((empty = TclCheckEmptyString(value1Ptr)) > 0) {
switch (TclCheckEmptyString(value2Ptr)) {
case -1:
s1 = "";
s1len = 0;
s2 = TclGetStringFromObj(value2Ptr, &s2len);
break;
case 0:
match = -1;
goto matchdone;
case 1:
default: /* avoid warn: `s2` may be used uninitialized */
match = 0;
goto matchdone;
}
} else if (TclCheckEmptyString(value2Ptr) > 0) {
switch (empty) {
case -1:
s2 = "";
s2len = 0;
s1 = TclGetStringFromObj(value1Ptr, &s1len);
break;
case 0:
match = 1;
goto matchdone;
case 1:
default: /* avoid warn: `s1` may be used uninitialized */
match = 0;
goto matchdone;
}
} else {
s1 = TclGetStringFromObj(value1Ptr, &s1len);
s2 = TclGetStringFromObj(value2Ptr, &s2len);
}
if (!nocase && checkEq) {
/*
* When we have equal-length we can check only for (in)equality.
* We can use memcmp in all (n)eq cases because we
* don't need to worry about lexical LE/BE variance.
*/
memCmpFn = memcmp;
} else {
/*
* As a catch-all we will work with UTF-8. We cannot use memcmp() as
* that is unsafe with any string containing NUL (\xC0\x80 in Tcl's
* utf rep). We can use the more efficient TclpUtfNcmp2 if we are
* case-sensitive and no specific length was requested.
*/
if ((reqlength < 0) && !nocase) {
memCmpFn = (memCmpFn_t) TclpUtfNcmp2;
} else {
s1len = Tcl_NumUtfChars(s1, s1len);
s2len = Tcl_NumUtfChars(s2, s2len);
memCmpFn = (memCmpFn_t) (nocase ? Tcl_UtfNcasecmp : Tcl_UtfNcmp);
}
}
s1 = TclGetStringFromObj(value1Ptr, &s1len);
s2 = TclGetStringFromObj(value2Ptr, &s2len);
}
length = (s1len < s2len) ? s1len : s2len;
if (reqlength > 0 && reqlength < length) {
length = reqlength;
} else if (reqlength < 0) {
if (!nocase && checkEq) {
/*
* The requested length is negative, so we ignore it by setting it to
* length + 1 so we correct the match var.
* When we have equal-length we can check only for (in)equality.
* We can use memcmp() in all (n)eq cases because we don't need to
* worry about lexical LE/BE variance.
*/
memCmpFn = memcmp;
} else {
/*
* As a catch-all we will work with UTF-8. We cannot use memcmp()
* as that is unsafe with any string containing NUL (\xC0\x80 in
* Tcl's utf rep). We can use the more efficient TclpUtfNcmp2 if
* we are case-sensitive and no specific length was requested.
*/
reqlength = length + 1;
if ((reqlength < 0) && !nocase) {
memCmpFn = (memCmpFn_t) TclpUtfNcmp2;
} else {
s1len = Tcl_NumUtfChars(s1, s1len);
s2len = Tcl_NumUtfChars(s2, s2len);
memCmpFn = (memCmpFn_t)
(nocase ? Tcl_UtfNcasecmp : Tcl_UtfNcmp);
}
}
if (checkEq && (s1len != s2len)) {
match = 1; /* This will be reversed below. */
} else {
/*
* The comparison function should compare up to the minimum
* byte length only.
*/
match = memCmpFn(s1, s2, (size_t) length);
}
if ((match == 0) && (reqlength > length)) {
match = s1len - s2len;
}
match = (match > 0) ? 1 : (match < 0) ? -1 : 0;
}
matchdone:
return match;
length = (s1len < s2len) ? s1len : s2len;
if (reqlength > 0 && reqlength < length) {
length = reqlength;
} else if (reqlength < 0) {
/*
* The requested length is negative, so we ignore it by setting it to
* length + 1 so we correct the match var.
*/
reqlength = length + 1;
}
if (checkEq && (s1len != s2len)) {
match = 1; /* This will be reversed below. */
} else {
/*
* The comparison function should compare up to the minimum byte
* length only.
*/
match = memCmpFn(s1, s2, (size_t) length);
}
if ((match == 0) && (reqlength > length)) {
match = s1len - s2len;
}
return (match > 0) ? 1 : (match < 0) ? -1 : 0;
}
int TclStringCmpOpts (
int TclStringCmpOpts(
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[], /* Argument objects. */
int *nocase,
int *reqlength
)
int *reqlength)
{
int i, length;
const char *string;
@@ -2873,10 +2893,10 @@ int TclStringCmpOpts (
for (i = 1; i < objc-2; i++) {
string = TclGetStringFromObj(objv[i], &length);
if ((length > 1) && !strncmp(string, "-nocase", (size_t)length)) {
if ((length > 1) && !strncmp(string, "-nocase", length)) {
*nocase = 1;
} else if ((length > 1)
&& !strncmp(string, "-length", (size_t)length)) {
&& !strncmp(string, "-length", length)) {
if (i+1 >= objc-2) {
goto str_cmp_args;
}
@@ -4229,7 +4249,7 @@ Tcl_TimeObjCmd(
* Use int obj since we know time is not fractional. [Bug 1202178]
*/
objs[0] = Tcl_NewIntObj((count <= 0) ? 0 : (int) totalMicroSec);
objs[0] = Tcl_NewWideIntObj((count <= 0) ? 0 : (Tcl_WideInt)totalMicroSec);
} else {
objs[0] = Tcl_NewDoubleObj(totalMicroSec/count);
}
+32 -28
View File
@@ -3408,10 +3408,10 @@ TclPushVarName(
int *isScalarPtr) /* Must not be NULL. */
{
register const char *p;
const char *name, *elName;
register int i, n;
const char *last, *name, *elName;
register int n;
Tcl_Token *elemTokenPtr = NULL;
int nameChars, elNameChars, simpleVarName, localIndex;
int nameLen, elNameLen, simpleVarName, localIndex;
int elemTokenCount = 0, allocedTokens = 0, removedParen = 0;
/*
@@ -3424,7 +3424,7 @@ TclPushVarName(
simpleVarName = 0;
name = elName = NULL;
nameChars = elNameChars = 0;
nameLen = elNameLen = 0;
localIndex = -1;
if (varTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
@@ -3436,22 +3436,25 @@ TclPushVarName(
simpleVarName = 1;
name = varTokenPtr[1].start;
nameChars = varTokenPtr[1].size;
if (name[nameChars-1] == ')') {
nameLen = varTokenPtr[1].size;
if (name[nameLen-1] == ')') {
/*
* last char is ')' => potential array reference.
*/
last = Tcl_UtfPrev(name + nameLen, name);
for (i=0,p=name ; i<nameChars ; i++,p++) {
if (*p == '(') {
elName = p + 1;
elNameChars = nameChars - i - 2;
nameChars = i;
break;
if (*last == ')') {
for (p = name; p < last; p = Tcl_UtfNext(p)) {
if (*p == '(') {
elName = p + 1;
elNameLen = last - elName;
nameLen = p - name;
break;
}
}
}
if (!(flags & TCL_NO_ELEMENT) && (elName != NULL) && elNameChars) {
if (!(flags & TCL_NO_ELEMENT) && elNameLen) {
/*
* An array element, the element name is a simple string:
* assemble the corresponding token.
@@ -3461,7 +3464,7 @@ TclPushVarName(
allocedTokens = 1;
elemTokenPtr->type = TCL_TOKEN_TEXT;
elemTokenPtr->start = elName;
elemTokenPtr->size = elNameChars;
elemTokenPtr->size = elNameLen;
elemTokenPtr->numComponents = 0;
elemTokenCount = 1;
}
@@ -3469,21 +3472,22 @@ TclPushVarName(
} else if (interp && ((n = varTokenPtr->numComponents) > 1)
&& (varTokenPtr[1].type == TCL_TOKEN_TEXT)
&& (varTokenPtr[n].type == TCL_TOKEN_TEXT)
&& (varTokenPtr[n].start[varTokenPtr[n].size - 1] == ')')) {
&& (*((p = varTokenPtr[n].start + varTokenPtr[n].size)-1) == ')')
&& (*Tcl_UtfPrev(p, varTokenPtr[n].start) == ')')) {
/*
* Check for parentheses inside first token.
*/
simpleVarName = 0;
for (i = 0, p = varTokenPtr[1].start;
i < varTokenPtr[1].size; i++, p++) {
for (p = varTokenPtr[1].start,
last = p + varTokenPtr[1].size; p < last; p = Tcl_UtfNext(p)) {
if (*p == '(') {
simpleVarName = 1;
break;
}
}
if (simpleVarName) {
int remainingChars;
int remainingLen;
/*
* Check the last token: if it is just ')', do not count it.
@@ -3499,13 +3503,13 @@ TclPushVarName(
}
name = varTokenPtr[1].start;
nameChars = p - varTokenPtr[1].start;
nameLen = p - varTokenPtr[1].start;
elName = p + 1;
remainingChars = (varTokenPtr[2].start - p) - 1;
elNameChars = (varTokenPtr[n].start-p) + varTokenPtr[n].size - 1;
remainingLen = (varTokenPtr[2].start - p) - 1;
elNameLen = (varTokenPtr[n].start-p) + varTokenPtr[n].size - 1;
if (!(flags & TCL_NO_ELEMENT)) {
if (remainingChars) {
if (remainingLen) {
/*
* Make a first token with the extra characters in the first
* token.
@@ -3515,7 +3519,7 @@ TclPushVarName(
allocedTokens = 1;
elemTokenPtr->type = TCL_TOKEN_TEXT;
elemTokenPtr->start = elName;
elemTokenPtr->size = remainingChars;
elemTokenPtr->size = remainingLen;
elemTokenPtr->numComponents = 0;
elemTokenCount = n;
@@ -3544,8 +3548,8 @@ TclPushVarName(
int hasNsQualifiers = 0;
for (i = 0, p = name; i < nameChars; i++, p++) {
if ((*p == ':') && ((i+1) < nameChars) && (*(p+1) == ':')) {
for (p = name, last = p + nameLen-1; p < last; p = Tcl_UtfNext(p)) {
if ((*p == ':') && (*(p+1) == ':')) {
hasNsQualifiers = 1;
break;
}
@@ -3558,7 +3562,7 @@ TclPushVarName(
*/
if (!hasNsQualifiers) {
localIndex = TclFindCompiledLocal(name, nameChars, 1, envPtr);
localIndex = TclFindCompiledLocal(name, nameLen, 1, envPtr);
if ((flags & TCL_NO_LARGE_INDEX) && (localIndex > 255)) {
/*
* We'll push the name.
@@ -3568,7 +3572,7 @@ TclPushVarName(
}
}
if (interp && localIndex < 0) {
PushLiteral(envPtr, name, nameChars);
PushLiteral(envPtr, name, nameLen);
}
/*
@@ -3577,7 +3581,7 @@ TclPushVarName(
*/
if (elName != NULL && !(flags & TCL_NO_ELEMENT)) {
if (elNameChars) {
if (elNameLen) {
TclCompileTokens(interp, elemTokenPtr, elemTokenCount,
envPtr);
} else {
+1 -1
View File
@@ -1496,7 +1496,7 @@ TclSubstCompile(
for (endTokenPtr = tokenPtr + parse.numTokens;
tokenPtr < endTokenPtr; tokenPtr = TokenAfter(tokenPtr)) {
int length, literal, catchRange, breakJump;
char buf[TCL_UTF_MAX];
char buf[TCL_UTF_MAX] = "";
JumpFixup startFixup, okFixup, returnFixup, breakFixup;
JumpFixup continueFixup, otherFixup, endFixup;
+2 -2
View File
@@ -1723,7 +1723,7 @@ TclWordKnownAtCompileTime(
case TCL_TOKEN_BS:
if (tempPtr != NULL) {
char utfBuf[TCL_UTF_MAX];
char utfBuf[TCL_UTF_MAX] = "";
int length = TclParseBackslash(tokenPtr->start,
tokenPtr->size, NULL, utfBuf);
@@ -2337,7 +2337,7 @@ TclCompileTokens(
{
Tcl_DString textBuffer; /* Holds concatenated chars from adjacent
* TCL_TOKEN_TEXT, TCL_TOKEN_BS tokens. */
char buffer[TCL_UTF_MAX];
char buffer[TCL_UTF_MAX] = "";
int i, numObjsToConcat, length, adjust;
unsigned char *entryCodeNext = envPtr->codeNext;
#define NUM_STATIC_POS 20
+12 -7
View File
@@ -1720,7 +1720,9 @@ LoadTableEncoding(
};
Tcl_DStringInit(&lineString);
Tcl_Gets(chan, &lineString);
if (Tcl_Gets(chan, &lineString) < 0) {
return NULL;
}
line = Tcl_DStringValue(&lineString);
fallback = (int) strtol(line, &line, 16);
@@ -1760,8 +1762,11 @@ LoadTableEncoding(
for (i = 0; i < numPages; i++) {
int ch;
const char *p;
int expected = 3 + 16 * (16 * 4 + 1);
Tcl_ReadChars(chan, objPtr, 3 + 16 * (16 * 4 + 1), 0);
if (Tcl_ReadChars(chan, objPtr, expected, 0) != expected) {
return NULL;
}
p = Tcl_GetString(objPtr);
hi = (staticHex[UCHAR(p[0])] << 4) + staticHex[UCHAR(p[1])];
dataPtr->toUnicode[hi] = pageMemPtr;
@@ -2360,8 +2365,8 @@ UtfToUtfProc(
src += len;
dst += Tcl_UniCharToUtf(*chPtr, dst);
#if TCL_UTF_MAX == 4
if (!len) {
src += TclUtfToUniChar(src, chPtr);
if ((*chPtr >= 0xD800) && (len < 3)) {
src += TclUtfToUniChar(src + len, chPtr);
dst += Tcl_UniCharToUtf(*chPtr, dst);
}
#endif
@@ -2982,7 +2987,7 @@ Iso88591FromUtfProc(
if (ch > 0xff
#if TCL_UTF_MAX == 4
|| !len
|| ((ch >= 0xD800) && (len < 3))
#endif
) {
if (flags & TCL_ENCODING_STOPONERROR) {
@@ -2990,7 +2995,7 @@ Iso88591FromUtfProc(
break;
}
#if TCL_UTF_MAX == 4
if (!len) len = 4;
if ((ch >= 0xD800) && (len < 3)) len = 4;
#endif
/*
@@ -3420,7 +3425,7 @@ EscapeFromUtfProc(
break;
}
memcpy(dst, subTablePtr->sequence,
(size_t) subTablePtr->sequenceLen);
subTablePtr->sequenceLen);
dst += subTablePtr->sequenceLen;
}
}
+35 -16
View File
@@ -2071,8 +2071,8 @@ TclResetRewriteEnsemble(
*
* TclSpellFix --
*
* Record a spelling correction that needs making in the
* generation of the WrongNumArgs usage message.
* Record a spelling correction that needs making in the generation of
* the WrongNumArgs usage message.
*
* Results:
* None.
@@ -2089,9 +2089,10 @@ FreeER(
Tcl_Interp *interp,
int result)
{
Tcl_Obj **tmp = (Tcl_Obj **)data[0];
Tcl_Obj **tmp = (Tcl_Obj **) data[0];
Tcl_Obj **store = (Tcl_Obj **) data[1];
ckfree(tmp[2]);
ckfree(store);
ckfree(tmp);
return result;
}
@@ -2117,22 +2118,28 @@ TclSpellFix(
iPtr->ensembleRewrite.numInsertedObjs = 0;
}
/* Compute the valid length of the ensemble root */
/*
* Compute the valid length of the ensemble root.
*/
size = iPtr->ensembleRewrite.numRemovedObjs + objc
- iPtr->ensembleRewrite.numInsertedObjs;
search = iPtr->ensembleRewrite.sourceObjs;
if (search[0] == NULL) {
/* Awful casting abuse here */
/*
* Awful casting abuse here!
*/
search = (Tcl_Obj *const *) search[1];
}
if (badIdx < iPtr->ensembleRewrite.numInsertedObjs) {
/*
* Misspelled value was inserted. We cannot directly jump
* to the bad value, but have to search.
* Misspelled value was inserted. We cannot directly jump to the bad
* value, but have to search.
*/
idx = 1;
while (idx < size) {
if (search[idx] == bad) {
@@ -2144,7 +2151,10 @@ TclSpellFix(
return;
}
} else {
/* Jump to the misspelled value. */
/*
* Jump to the misspelled value.
*/
idx = iPtr->ensembleRewrite.numRemovedObjs + badIdx
- iPtr->ensembleRewrite.numInsertedObjs;
@@ -2156,17 +2166,26 @@ TclSpellFix(
search = iPtr->ensembleRewrite.sourceObjs;
if (search[0] == NULL) {
store = (Tcl_Obj **)search[2];
store = (Tcl_Obj **) search[2];
} else {
Tcl_Obj **tmp = ckalloc(3 * sizeof(Tcl_Obj *));
tmp[0] = NULL;
tmp[1] = (Tcl_Obj *)iPtr->ensembleRewrite.sourceObjs;
tmp[2] = (Tcl_Obj *)ckalloc(size * sizeof(Tcl_Obj *));
memcpy(tmp[2], tmp[1], size*sizeof(Tcl_Obj *));
store = ckalloc(size * sizeof(Tcl_Obj *));
memcpy(store, iPtr->ensembleRewrite.sourceObjs,
size * sizeof(Tcl_Obj *));
/*
* Awful casting abuse here! Note that the NULL in the first element
* indicates that the initial objects are a raw array in the second
* element and the rewritten ones are a raw array in the third.
*/
tmp[0] = NULL;
tmp[1] = (Tcl_Obj *) iPtr->ensembleRewrite.sourceObjs;
tmp[2] = (Tcl_Obj *) store;
iPtr->ensembleRewrite.sourceObjs = (Tcl_Obj *const *) tmp;
TclNRAddCallback(interp, FreeER, tmp, NULL, NULL, NULL);
store = (Tcl_Obj **)tmp[2];
TclNRAddCallback(interp, FreeER, tmp, store, NULL, NULL);
}
store[idx] = fix;
+8 -4
View File
@@ -2014,7 +2014,7 @@ ArgumentBCEnter(
*----------------------------------------------------------------------
*/
#define bcFramePtr (&TD->cmdFrame)
#define initCatchTop ((ptrdiff_t *) (&TD->stack[-1]))
#define initCatchTop ((ptrdiff_t *) (TD->stack-1))
#define initTosPtr ((Tcl_Obj **) (initCatchTop+codePtr->maxExceptDepth))
#define esPtr (iPtr->execEnvPtr->execStackPtr)
@@ -5237,8 +5237,12 @@ TEBCresume(
/* Every range of an empty list is an empty list */
if (objc == 0) {
TRACE_APPEND(("\n"));
NEXT_INST_F(9, 0, 0);
/* avoid return of not canonical list (e. g. spaces in string repr.) */
if (!valuePtr->bytes || !valuePtr->length) {
TRACE_APPEND(("\n"));
NEXT_INST_F(9, 0, 0);
}
goto emptyList;
}
/* Decode index value operands. */
@@ -5511,7 +5515,7 @@ TEBCresume(
objResultPtr = Tcl_NewStringObj((const char *)
valuePtr->bytes+index, 1);
} else {
char buf[TCL_UTF_MAX];
char buf[TCL_UTF_MAX] = "";
Tcl_UniChar ch = Tcl_GetUniChar(valuePtr, index);
/*
+1 -1
View File
@@ -180,7 +180,7 @@ FileCopyRename(
}
jargv[0] = objv[objc - 1];
jargv[1] = source;
newFileName = TclJoinPath(2, jargv);
newFileName = TclJoinPath(2, jargv, 1);
Tcl_IncrRefCount(newFileName);
result = CopyRenameOneFile(interp, objv[i], newFileName, copyFlag,
force);
+4 -4
View File
@@ -808,24 +808,24 @@ Tcl_FSJoinToPath(
Tcl_Obj *const objv[]) /* Path elements to join. */
{
if (pathPtr == NULL) {
return TclJoinPath(objc, objv);
return TclJoinPath(objc, objv, 0);
}
if (objc == 0) {
return TclJoinPath(1, &pathPtr);
return TclJoinPath(1, &pathPtr, 0);
}
if (objc == 1) {
Tcl_Obj *pair[2];
pair[0] = pathPtr;
pair[1] = objv[0];
return TclJoinPath(2, pair);
return TclJoinPath(2, pair, 0);
} else {
int elemc = objc + 1;
Tcl_Obj *ret, **elemv = ckalloc(elemc*sizeof(Tcl_Obj *));
elemv[0] = pathPtr;
memcpy(elemv+1, objv, objc*sizeof(Tcl_Obj *));
ret = TclJoinPath(elemc, elemv);
ret = TclJoinPath(elemc, elemv, 0);
ckfree(elemv);
return ret;
}
+1 -1
View File
@@ -897,7 +897,7 @@ TclDatelex(
location->first_column = yyInput - info->dateStart;
for ( ; ; ) {
while (isspace(UCHAR(*yyInput))) {
while (TclIsSpaceProc(*yyInput)) {
yyInput++;
}
+6 -6
View File
@@ -902,9 +902,8 @@ typedef struct CompiledLocal {
/* Next compiler-recognized local variable for
* this procedure, or NULL if this is the last
* local. */
int nameLength; /* The number of characters in local
* variable's name. Used to speed up variable
* lookups. */
int nameLength; /* The number of bytes in local variable's name.
* Among others used to speed up var lookups. */
int frameIndex; /* Index in the array of compiler-assigned
* variables in the procedure call frame. */
int flags; /* Flag bits for the local variable. Same as
@@ -3025,9 +3024,10 @@ MODULE_SCOPE void TclInitNotifier(void);
MODULE_SCOPE void TclInitObjSubsystem(void);
MODULE_SCOPE void TclInitSubsystems(void);
MODULE_SCOPE int TclInterpReady(Tcl_Interp *interp);
MODULE_SCOPE int TclIsSpaceProc(char byte);
MODULE_SCOPE int TclIsBareword(char byte);
MODULE_SCOPE Tcl_Obj * TclJoinPath(int elements, Tcl_Obj * const objv[]);
MODULE_SCOPE int TclIsSpaceProc(int byte);
MODULE_SCOPE int TclIsBareword(int byte);
MODULE_SCOPE Tcl_Obj * TclJoinPath(int elements, Tcl_Obj * const objv[],
int forceRelative);
MODULE_SCOPE int TclJoinThread(Tcl_ThreadId id, int *result);
MODULE_SCOPE void TclLimitRemoveAllHandlers(Tcl_Interp *interp);
MODULE_SCOPE Tcl_Obj * TclLindexList(Tcl_Interp *interp,
-1
View File
@@ -15,7 +15,6 @@
#ifndef _TCLINTDECLS
#define _TCLINTDECLS
#include "tclPort.h"
#undef TCL_STORAGE_CLASS
#ifdef BUILD_tcl
+26 -15
View File
@@ -200,25 +200,36 @@ TclCreateLiteral(
for (globalPtr=globalTablePtr->buckets[globalHash] ; globalPtr!=NULL;
globalPtr = globalPtr->nextPtr) {
objPtr = globalPtr->objPtr;
if ((globalPtr->nsPtr == nsPtr)
&& (objPtr->length == length) && ((length == 0)
|| ((objPtr->bytes[0] == bytes[0])
&& (memcmp(objPtr->bytes, bytes, (unsigned) length) == 0)))) {
if (globalPtr->nsPtr == nsPtr) {
/*
* A literal was found: return it
* Literals should always have UTF-8 representations... but this
* is not guaranteed so we need to be careful anyway.
*
* https://stackoverflow.com/q/54337750/301832
*/
if (newPtr) {
*newPtr = 0;
int objLength;
char *objBytes = TclGetStringFromObj(objPtr, &objLength);
if ((objLength == length) && ((length == 0)
|| ((objBytes[0] == bytes[0])
&& (memcmp(objBytes, bytes, (unsigned) length) == 0)))) {
/*
* A literal was found: return it
*/
if (newPtr) {
*newPtr = 0;
}
if (globalPtrPtr) {
*globalPtrPtr = globalPtr;
}
if (flags & LITERAL_ON_HEAP) {
ckfree(bytes);
}
globalPtr->refCount++;
return objPtr;
}
if (globalPtrPtr) {
*globalPtrPtr = globalPtr;
}
if ((flags & LITERAL_ON_HEAP)) {
ckfree(bytes);
}
globalPtr->refCount++;
return objPtr;
}
}
if (!newPtr) {
+8 -6
View File
@@ -114,12 +114,14 @@ TclOOInitInfo(
*/
infoCmd = Tcl_FindCommand(interp, "info", NULL, TCL_GLOBAL_ONLY);
Tcl_GetEnsembleMappingDict(NULL, infoCmd, &mapDict);
Tcl_DictObjPut(NULL, mapDict, Tcl_NewStringObj("object", -1),
Tcl_NewStringObj("::oo::InfoObject", -1));
Tcl_DictObjPut(NULL, mapDict, Tcl_NewStringObj("class", -1),
Tcl_NewStringObj("::oo::InfoClass", -1));
Tcl_SetEnsembleMappingDict(interp, infoCmd, mapDict);
if (infoCmd) {
Tcl_GetEnsembleMappingDict(NULL, infoCmd, &mapDict);
Tcl_DictObjPut(NULL, mapDict, Tcl_NewStringObj("object", -1),
Tcl_NewStringObj("::oo::InfoObject", -1));
Tcl_DictObjPut(NULL, mapDict, Tcl_NewStringObj("class", -1),
Tcl_NewStringObj("::oo::InfoClass", -1));
Tcl_SetEnsembleMappingDict(interp, infoCmd, mapDict);
}
}
/*
+2 -4
View File
@@ -970,10 +970,8 @@ ProcedureMethodVarResolver(
* Must not retain reference to resolved information. [Bug 3105999]
*/
if (rPtr != NULL) {
rPtr->deleteProc(rPtr);
}
return (*varPtr? TCL_OK : TCL_CONTINUE);
rPtr->deleteProc(rPtr);
return (*varPtr ? TCL_OK : TCL_CONTINUE);
}
static Tcl_Var
+6 -6
View File
@@ -613,7 +613,7 @@ Tcl_ParseCommand(
int
TclIsSpaceProc(
char byte)
int byte)
{
return CHAR_TYPE(byte) & (TYPE_SPACE) || byte == '\n';
}
@@ -642,7 +642,7 @@ TclIsSpaceProc(
int
TclIsBareword(
char byte)
int byte)
{
if (byte < '0' || byte > 'z') {
return 0;
@@ -844,7 +844,7 @@ TclParseBackslash(
Tcl_UniChar unichar = 0;
int result;
int count;
char buf[TCL_UTF_MAX];
char buf[TCL_UTF_MAX] = "";
if (numBytes == 0) {
if (readPtr != NULL) {
@@ -993,8 +993,8 @@ TclParseBackslash(
}
count = Tcl_UniCharToUtf(result, dst);
#if TCL_UTF_MAX > 3
if (!count) {
count = Tcl_UniCharToUtf(-1, dst);
if ((result >= 0xD800) && (count < 3)) {
count += Tcl_UniCharToUtf(-1, dst + count);
}
#endif
return count;
@@ -2217,7 +2217,7 @@ TclSubstTokens(
Tcl_Obj *appendObj = NULL;
const char *append = NULL;
int appendByteLength = 0;
char utfCharBytes[TCL_UTF_MAX];
char utfCharBytes[TCL_UTF_MAX] = "";
switch (tokenPtr->type) {
case TCL_TOKEN_TEXT:
+1 -1
View File
@@ -12,6 +12,6 @@
#define TYPE_CLOSE_BRACK 0x20
#define TYPE_BRACE 0x40
#define CHAR_TYPE(c) (tclCharTypeTable+128)[(int)(c)]
#define CHAR_TYPE(c) (tclCharTypeTable+128)[(unsigned char)(c)]
MODULE_SCOPE const char tclCharTypeTable[];
+42 -36
View File
@@ -829,7 +829,7 @@ Tcl_FSJoinPath(
* reference count. */
int elements) /* Number of elements to use (-1 = all) */
{
Tcl_Obj *copy, *res;
Tcl_Obj *res;
int objc;
Tcl_Obj **objv;
@@ -838,17 +838,17 @@ Tcl_FSJoinPath(
}
elements = ((elements >= 0) && (elements <= objc)) ? elements : objc;
copy = TclListObjCopy(NULL, listObj);
Tcl_ListObjGetElements(NULL, listObj, &objc, &objv);
res = TclJoinPath(elements, objv);
Tcl_DecrRefCount(copy);
res = TclJoinPath(elements, objv, 0);
return res;
}
Tcl_Obj *
TclJoinPath(
int elements,
Tcl_Obj * const objv[])
int elements, /* Number of elements to use (-1 = all) */
Tcl_Obj * const objv[], /* Path elements to join */
int forceRelative) /* If non-zero, assume all more paths are
* relative (e. g. simple normalization) */
{
Tcl_Obj *res = NULL;
int i;
@@ -879,10 +879,13 @@ TclJoinPath(
if ((elt->typePtr == &tclFsPathType)
&& !((elt->bytes != NULL) && (elt->bytes[0] == '\0'))
&& TclGetPathType(elt, NULL, NULL, NULL) == TCL_PATH_ABSOLUTE) {
Tcl_Obj *tailObj = objv[1];
Tcl_PathType type = TclGetPathType(tailObj, NULL, NULL, NULL);
&& TclGetPathType(elt, NULL, NULL, NULL) == TCL_PATH_ABSOLUTE) {
Tcl_Obj *tailObj = objv[1];
Tcl_PathType type;
/* if forceRelative - second path is relative */
type = forceRelative ? TCL_PATH_RELATIVE :
TclGetPathType(tailObj, NULL, NULL, NULL);
if (type == TCL_PATH_RELATIVE) {
const char *str;
int len;
@@ -960,7 +963,9 @@ TclJoinPath(
strElt = Tcl_GetStringFromObj(elt, &strEltLen);
driveNameLength = 0;
type = TclGetPathType(elt, &fsPtr, &driveNameLength, &driveName);
/* if forceRelative - all paths excepting first one are relative */
type = (forceRelative && (i > 0)) ? TCL_PATH_RELATIVE :
TclGetPathType(elt, &fsPtr, &driveNameLength, &driveName);
if (type != TCL_PATH_RELATIVE) {
/*
* Zero out the current result.
@@ -1359,6 +1364,7 @@ TclNewFSPathObj(
count = 0;
state = 1;
}
break;
case 1: /* Scanning for next dirsep */
switch (*p) {
case '/':
@@ -2359,36 +2365,29 @@ SetFsPathFromAny(
* Handle tilde substitutions, if needed.
*/
if (name[0] == '~') {
if (len && name[0] == '~') {
Tcl_DString temp;
int split;
char separator = '/';
/*
* We have multiple cases '~/foo/bar...', '~user/foo/bar...', etc.
* split becomes value 1 for '~/...' as well as for '~'.
*/
split = FindSplitPos(name, separator);
if (split != len) {
/*
* We have multiple pieces '~user/foo/bar...'
*/
name[split] = '\0';
}
/*
* Do some tilde substitution.
*/
if (name[1] == '\0') {
if (split == 1) {
/*
* We have just '~'
* We have just '~' (or '~/...')
*/
const char *dir;
Tcl_DString dirString;
if (split != len) {
name[split] = separator;
}
dir = TclGetEnv("HOME", &dirString);
if (dir == NULL) {
if (interp) {
@@ -2408,23 +2407,26 @@ SetFsPathFromAny(
* We have a user name '~user'
*/
const char *expandedUser;
Tcl_DString userName;
Tcl_DStringInit(&userName);
Tcl_DStringAppend(&userName, name+1, split-1);
expandedUser = Tcl_DStringValue(&userName);
Tcl_DStringInit(&temp);
if (TclpGetUserHome(name+1, &temp) == NULL) {
if (TclpGetUserHome(expandedUser, &temp) == NULL) {
if (interp != NULL) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"user \"%s\" doesn't exist", name+1));
"user \"%s\" doesn't exist", expandedUser));
Tcl_SetErrorCode(interp, "TCL", "VALUE", "PATH", "NOUSER",
NULL);
}
Tcl_DStringFree(&userName);
Tcl_DStringFree(&temp);
if (split != len) {
name[split] = separator;
}
return TCL_ERROR;
}
if (split != len) {
name[split] = separator;
}
Tcl_DStringFree(&userName);
}
transPtr = TclDStringToObj(&temp);
@@ -2461,13 +2463,17 @@ SetFsPathFromAny(
pair[0] = transPtr;
pair[1] = Tcl_NewStringObj(name+split+1, -1);
transPtr = TclJoinPath(2, pair);
Tcl_DecrRefCount(pair[0]);
Tcl_DecrRefCount(pair[1]);
transPtr = TclJoinPath(2, pair, 1);
if (transPtr != pair[0]) {
Tcl_DecrRefCount(pair[0]);
}
if (transPtr != pair[1]) {
Tcl_DecrRefCount(pair[1]);
}
}
}
} else {
transPtr = TclJoinPath(1, &pathPtr);
transPtr = TclJoinPath(1, &pathPtr, 1);
}
/*
+26 -30
View File
@@ -371,11 +371,9 @@ TclCreateProc(
Interp *iPtr = (Interp *) interp;
register Proc *procPtr;
int i, result, numArgs, plen;
const char *bytes, *argname, *argnamei;
char argnamelast;
int i, result, numArgs;
register CompiledLocal *localPtr = NULL;
Tcl_Obj *defPtr, *errorObj, **argArray;
Tcl_Obj **argArray;
int precompiled = 0;
if (bodyPtr->typePtr == &tclProcBodyType) {
@@ -412,6 +410,7 @@ TclCreateProc(
*/
if (Tcl_IsShared(bodyPtr)) {
const char *bytes;
int length;
Tcl_Obj *sharedBodyPtr = bodyPtr;
@@ -474,7 +473,8 @@ TclCreateProc(
}
for (i = 0; i < numArgs; i++) {
int fieldCount, nameLength, valueLength;
const char *argname, *argnamei, *argnamelast;
int fieldCount, nameLength;
Tcl_Obj **fieldValues;
/*
@@ -487,7 +487,7 @@ TclCreateProc(
goto procError;
}
if (fieldCount > 2) {
errorObj = Tcl_NewStringObj(
Tcl_Obj *errorObj = Tcl_NewStringObj(
"too many fields in argument specifier \"", -1);
Tcl_AppendObjToObj(errorObj, argArray[i]);
Tcl_AppendToObj(errorObj, "\"", -1);
@@ -504,24 +504,17 @@ TclCreateProc(
goto procError;
}
argname = Tcl_GetStringFromObj(fieldValues[0], &plen);
nameLength = Tcl_NumUtfChars(argname, plen);
if (fieldCount == 2) {
const char * value = TclGetString(fieldValues[1]);
valueLength = Tcl_NumUtfChars(value, fieldValues[1]->length);
} else {
valueLength = 0;
}
argname = Tcl_GetStringFromObj(fieldValues[0], &nameLength);
/*
* Check that the formal parameter name is a scalar.
*/
argnamei = argname;
argnamelast = argname[plen-1];
while (plen--) {
if (argnamei[0] == '(') {
if (argnamelast == ')') { /* We have an array element. */
argnamelast = Tcl_UtfPrev(argname + nameLength, argname);
while (argnamei < argnamelast) {
if (*argnamei == '(') {
if (*argnamelast == ')') { /* We have an array element. */
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"formal parameter \"%s\" is an array element",
Tcl_GetString(fieldValues[0])));
@@ -529,8 +522,9 @@ TclCreateProc(
"FORMALARGUMENTFORMAT", NULL);
goto procError;
}
} else if ((argnamei[0] == ':') && (argnamei[1] == ':')) {
errorObj = Tcl_NewStringObj("formal parameter \"", -1);
} else if (*argnamei == ':' && *(argnamei+1) == ':') {
Tcl_Obj *errorObj = Tcl_NewStringObj(
"formal parameter \"", -1);
Tcl_AppendObjToObj(errorObj, fieldValues[0]);
Tcl_AppendToObj(errorObj, "\" is not a simple name", -1);
Tcl_SetObjResult(interp, errorObj);
@@ -554,7 +548,7 @@ TclCreateProc(
*/
if ((localPtr->nameLength != nameLength)
|| (Tcl_UtfNcmp(localPtr->name, argname, nameLength))
|| (memcmp(localPtr->name, argname, nameLength) != 0)
|| (localPtr->frameIndex != i)
|| !(localPtr->flags & VAR_ARGUMENT)
|| (localPtr->defValuePtr == NULL && fieldCount == 2)
@@ -572,14 +566,17 @@ TclCreateProc(
*/
if (localPtr->defValuePtr != NULL) {
int tmpLength;
int tmpLength, valueLength;
const char *tmpPtr = TclGetStringFromObj(localPtr->defValuePtr,
&tmpLength);
const char *value = TclGetStringFromObj(fieldValues[1],
&valueLength);
if ((valueLength != tmpLength) ||
Tcl_UtfNcmp(Tcl_GetString(fieldValues[1]), tmpPtr, tmpLength)) {
errorObj = Tcl_ObjPrintf(
"procedure \"%s\": formal parameter \"" ,procName);
if ((valueLength != tmpLength)
|| memcmp(value, tmpPtr, tmpLength) != 0
) {
Tcl_Obj *errorObj = Tcl_ObjPrintf(
"procedure \"%s\": formal parameter \"", procName);
Tcl_AppendObjToObj(errorObj, fieldValues[0]);
Tcl_AppendToObj(errorObj, "\" has "
"default value inconsistent with precompiled body", -1);
@@ -626,7 +623,7 @@ TclCreateProc(
if ((i == numArgs - 1)
&& (localPtr->nameLength == 4)
&& (localPtr->name[0] == 'a')
&& (strcmp(localPtr->name, "args") == 0)) {
&& (memcmp(localPtr->name, "args", 4) == 0)) {
localPtr->flags |= VAR_IS_ARGS;
}
}
@@ -644,9 +641,8 @@ TclCreateProc(
localPtr = procPtr->firstLocalPtr;
procPtr->firstLocalPtr = localPtr->nextPtr;
defPtr = localPtr->defValuePtr;
if (defPtr != NULL) {
Tcl_DecrRefCount(defPtr);
if (localPtr->defValuePtr != NULL) {
Tcl_DecrRefCount(localPtr->defValuePtr);
}
ckfree(localPtr);
+4 -4
View File
@@ -134,7 +134,7 @@ BuildCharSet(
* as well as the dash.
*/
if (*format == ']') {
if (*format == ']' || !cset->ranges) {
cset->chars[cset->nchars++] = start;
cset->chars[cset->nchars++] = ch;
} else {
@@ -260,7 +260,7 @@ ValidateFormat(
Tcl_UniChar ch = 0;
int objIndex, xpgSize, nspace = numVars;
int *nassign = TclStackAlloc(interp, nspace * sizeof(int));
char buf[TCL_UTF_MAX+1];
char buf[TCL_UTF_MAX+1] = "";
Tcl_Obj *errorMsg; /* Place to build an error messages. Note that
* these are messy operations because we do
* not want to use the formatting engine;
@@ -888,8 +888,8 @@ Tcl_ScanObjCmd(
offset = TclUtfToUniChar(string, &sch);
i = (int)sch;
#if TCL_UTF_MAX == 4
if (!offset) {
offset = Tcl_UtfToUniChar(string, &sch);
if ((sch >= 0xD800) && (offset < 3)) {
offset += TclUtfToUniChar(string+offset, &sch);
i = (((i<<10) & 0x0FFC00) + 0x10000) + (sch & 0x3FF);
}
#endif
+4 -4
View File
@@ -2002,9 +2002,9 @@ Tcl_AppendFormatToObj(
}
length = Tcl_UniCharToUtf(code, buf);
#if TCL_UTF_MAX > 3
if (!length) {
/* Special case for handling upper surrogates. */
length = Tcl_UniCharToUtf(-1, buf);
if ((code >= 0xD800) && (length < 3)) {
/* Special case for handling high surrogates. */
length += Tcl_UniCharToUtf(-1, buf + length);
}
#endif
segment = Tcl_NewStringObj(buf, length);
@@ -3176,7 +3176,7 @@ ExtendStringRepWithUnicode(
copyBytes:
dst = objPtr->bytes + origLength;
for (i = 0; i < numChars; i++) {
dst += Tcl_UniCharToUtf((int) unicode[i], dst);
dst += Tcl_UniCharToUtf(unicode[i], dst);
}
*dst = '\0';
objPtr->length = dst - objPtr->bytes;
+93
View File
@@ -188,11 +188,68 @@ Tcl_WinUtfToTChar(
int len,
Tcl_DString *dsPtr)
{
#if TCL_UTF_MAX > 4
Tcl_UniChar ch = 0;
wchar_t *w, *wString;
const char *p, *end;
int oldLength;
#endif
Tcl_DStringInit(dsPtr);
if (!string) {
return NULL;
}
#if TCL_UTF_MAX > 4
if (len < 0) {
len = strlen(string);
}
/*
* Unicode string length in Tcl_UniChars will be <= UTF-8 string length in
* bytes.
*/
oldLength = Tcl_DStringLength(dsPtr);
Tcl_DStringSetLength(dsPtr,
oldLength + (int) ((len + 1) * sizeof(wchar_t)));
wString = (wchar_t *) (Tcl_DStringValue(dsPtr) + oldLength);
w = wString;
p = string;
end = string + len - 4;
while (p < end) {
p += TclUtfToUniChar(p, &ch);
if (ch > 0xFFFF) {
*w++ = (wchar_t) (0xD800 + ((ch -= 0x10000) >> 10));
*w++ = (wchar_t) (0xDC00 | (ch & 0x3FF));
} else {
*w++ = ch;
}
}
end += 4;
while (p < end) {
if (Tcl_UtfCharComplete(p, end-p)) {
p += TclUtfToUniChar(p, &ch);
} else {
ch = UCHAR(*p++);
}
if (ch > 0xFFFF) {
*w++ = (wchar_t) (0xD800 + ((ch -= 0x10000) >> 10));
*w++ = (wchar_t) (0xDC00 | (ch & 0x3FF));
} else {
*w++ = ch;
}
}
*w = '\0';
Tcl_DStringSetLength(dsPtr,
oldLength + ((char *) w - (char *) wString));
return (char *)wString;
#else
return (char *)Tcl_UtfToUniCharDString(string, len, dsPtr);
#endif
}
char *
@@ -201,6 +258,12 @@ Tcl_WinTCharToUtf(
int len,
Tcl_DString *dsPtr)
{
#if TCL_UTF_MAX > 4
const wchar_t *w, *wEnd;
char *p, *result;
int oldLength, blen = 1;
#endif
Tcl_DStringInit(dsPtr);
if (!string) {
return NULL;
@@ -210,7 +273,36 @@ Tcl_WinTCharToUtf(
} else {
len /= 2;
}
#if TCL_UTF_MAX > 4
oldLength = Tcl_DStringLength(dsPtr);
Tcl_DStringSetLength(dsPtr, oldLength + (len + 1) * 4);
result = Tcl_DStringValue(dsPtr) + oldLength;
p = result;
wEnd = (wchar_t *)string + len;
for (w = (wchar_t *)string; w < wEnd; ) {
if (!blen && ((*w & 0xFC00) != 0xDC00)) {
/* Special case for handling high surrogates. */
p += Tcl_UniCharToUtf(-1, p);
}
blen = Tcl_UniCharToUtf(*w, p);
p += blen;
if ((*w >= 0xD800) && (blen < 3)) {
/* Indication that high surrogate is handled */
blen = 0;
}
w++;
}
if (!blen) {
/* Special case for handling high surrogates. */
p += Tcl_UniCharToUtf(-1, p);
}
Tcl_DStringSetLength(dsPtr, oldLength + (p - result));
return result;
#else
return Tcl_UniCharToUtfDString((Tcl_UniChar *)string, len, dsPtr);
#endif
}
#if defined(TCL_WIDE_INT_IS_LONG)
@@ -761,6 +853,7 @@ const TclTomMathStubs tclTomMathStubs = {
TclBNInitBignumFromLong, /* 64 */
TclBNInitBignumFromWideInt, /* 65 */
TclBNInitBignumFromWideUInt, /* 66 */
TclBN_mp_expt_d_ex, /* 67 */
};
static const TclStubHooks tclStubHooks = {
+56 -1
View File
@@ -220,6 +220,9 @@ static void SpecialFree(char *blockPtr);
static int StaticInitProc(Tcl_Interp *interp);
static int TestasyncCmd(ClientData dummy,
Tcl_Interp *interp, int argc, const char **argv);
static int TestpurebytesobjObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
static int TestbytestringObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
@@ -570,6 +573,7 @@ Tcltest_Init(
Tcl_CreateObjCommand(interp, "gettimes", GetTimesObjCmd, NULL, NULL);
Tcl_CreateCommand(interp, "noop", NoopCmd, NULL, NULL);
Tcl_CreateObjCommand(interp, "noop", NoopObjCmd, NULL, NULL);
Tcl_CreateObjCommand(interp, "testpurebytesobj", TestpurebytesobjObjCmd, NULL, NULL);
Tcl_CreateObjCommand(interp, "testbytestring", TestbytestringObjCmd, NULL, NULL);
Tcl_CreateObjCommand(interp, "testwrongnumargs", TestWrongNumArgsObjCmd,
NULL, NULL);
@@ -2081,7 +2085,7 @@ TestevalexObjCmd(
flags = 0;
if (objc == 3) {
const char *global = Tcl_GetStringFromObj(objv[2], &length);
const char *global = Tcl_GetString(objv[2]);
if (strcmp(global, "global") != 0) {
Tcl_AppendResult(interp, "bad value \"", global,
"\": must be global", NULL);
@@ -4956,6 +4960,57 @@ NoopObjCmd(
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
* TestpurebytesobjObjCmd --
*
* This object-based procedure constructs a pure bytes object
* without type and with internal representation containing NULL's.
*
* If no argument supplied it returns empty object with tclEmptyStringRep,
* otherwise it returns this as pure bytes object with bytes value equal
* string.
*
* Results:
* Returns the TCL_OK result code.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
static int
TestpurebytesobjObjCmd(
ClientData unused, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* The argument objects. */
{
Tcl_Obj *objPtr;
if (objc > 2) {
Tcl_WrongNumArgs(interp, 1, objv, "?string?");
return TCL_ERROR;
}
objPtr = Tcl_NewObj();
/*
objPtr->internalRep.twoPtrValue.ptr1 = NULL;
objPtr->internalRep.twoPtrValue.ptr2 = NULL;
*/
memset(&objPtr->internalRep, 0, sizeof(objPtr->internalRep));
if (objc == 2) {
const char *s = Tcl_GetString(objv[1]);
objPtr->length = objv[1]->length;
objPtr->bytes = ckalloc(objPtr->length + 1);
memcpy(objPtr->bytes, s, objPtr->length);
objPtr->bytes[objPtr->length] = 0;
}
Tcl_SetObjResult(interp, objPtr);
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
+46 -1
View File
@@ -21,13 +21,14 @@
*/
static const char packageName[] = "procbodytest";
static const char packageVersion[] = "1.0";
static const char packageVersion[] = "1.1";
/*
* Name of the commands exported by this package
*/
static const char procCommand[] = "proc";
static const char checkCommand[] = "check";
/*
* this struct describes an entry in the table of command names and command
@@ -46,6 +47,8 @@ typedef struct CmdTable {
static int ProcBodyTestProcObjCmd(ClientData dummy,
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]);
static int ProcBodyTestCheckObjCmd(ClientData dummy,
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]);
static int ProcBodyTestInitInternal(Tcl_Interp *interp, int isSafe);
static int RegisterCommand(Tcl_Interp* interp,
const char *namespace, const CmdTable *cmdTablePtr);
@@ -57,11 +60,13 @@ static int RegisterCommand(Tcl_Interp* interp,
static const CmdTable commands[] = {
{ procCommand, ProcBodyTestProcObjCmd, 1 },
{ checkCommand, ProcBodyTestCheckObjCmd, 1 },
{ 0, 0, 0 }
};
static const CmdTable safeCommands[] = {
{ procCommand, ProcBodyTestProcObjCmd, 1 },
{ checkCommand, ProcBodyTestCheckObjCmd, 1 },
{ 0, 0, 0 }
};
@@ -300,6 +305,46 @@ ProcBodyTestProcObjCmd(
return result;
}
/*
*----------------------------------------------------------------------
*
* ProcBodyTestCheckObjCmd --
*
* Implements the "procbodytest::check" command. Here is the command
* description:
* procbodytest::check
*
* Performs an internal check that the Tcl_PkgPresent() command returns
* the same version number as was registered when the procbodytest package
* was provided. Places a boolean in the interp result indicating the
* test outcome.
*
* Results:
* Returns a standard Tcl code.
*
*----------------------------------------------------------------------
*/
static int
ProcBodyTestCheckObjCmd(
ClientData dummy, /* context; not used */
Tcl_Interp *interp, /* the current interpreter */
int objc, /* argument count */
Tcl_Obj *const objv[]) /* arguments */
{
const char *version;
if (objc != 1) {
Tcl_WrongNumArgs(interp, 1, objv, "");
return TCL_ERROR;
}
version = Tcl_PkgPresent(interp, packageName, packageVersion, 1);
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(
strcmp(version, packageVersion) == 0));
return TCL_OK;
}
/*
* Local Variables:
* mode: c
+39 -34
View File
@@ -30,13 +30,13 @@ declare 1 {
}
declare 2 {
int TclBN_mp_add(mp_int *a, mp_int *b, mp_int *c)
int TclBN_mp_add(const mp_int *a, const mp_int *b, mp_int *c)
}
declare 3 {
int TclBN_mp_add_d(mp_int *a, mp_digit b, mp_int *c)
int TclBN_mp_add_d(const mp_int *a, mp_digit b, mp_int *c)
}
declare 4 {
int TclBN_mp_and(mp_int *a, mp_int *b, mp_int *c)
int TclBN_mp_and(const mp_int *a, const mp_int *b, mp_int *c)
}
declare 5 {
void TclBN_mp_clamp(mp_int *a)
@@ -63,25 +63,25 @@ declare 12 {
int TclBN_mp_count_bits(const mp_int *a)
}
declare 13 {
int TclBN_mp_div(mp_int *a, mp_int *b, mp_int *q, mp_int *r)
int TclBN_mp_div(const mp_int *a, const mp_int *b, mp_int *q, mp_int *r)
}
declare 14 {
int TclBN_mp_div_d(mp_int *a, mp_digit b, mp_int *q, mp_digit *r)
int TclBN_mp_div_d(const mp_int *a, mp_digit b, mp_int *q, mp_digit *r)
}
declare 15 {
int TclBN_mp_div_2(mp_int *a, mp_int *q)
int TclBN_mp_div_2(const mp_int *a, mp_int *q)
}
declare 16 {
int TclBN_mp_div_2d(const mp_int *a, int b, mp_int *q, mp_int *r)
}
declare 17 {
int TclBN_mp_div_3(mp_int *a, mp_int *q, mp_digit *r)
int TclBN_mp_div_3(const mp_int *a, mp_int *q, mp_digit *r)
}
declare 18 {
void TclBN_mp_exch(mp_int *a, mp_int *b)
}
declare 19 {
int TclBN_mp_expt_d(mp_int *a, mp_digit b, mp_int *c)
int TclBN_mp_expt_d(const mp_int *a, mp_digit b, mp_int *c)
}
declare 20 {
int TclBN_mp_grow(mp_int *a, int size)
@@ -90,7 +90,7 @@ declare 21 {
int TclBN_mp_init(mp_int *a)
}
declare 22 {
int TclBN_mp_init_copy(mp_int *a, mp_int *b)
int TclBN_mp_init_copy(mp_int *a, const mp_int *b)
}
declare 23 {
int TclBN_mp_init_multi(mp_int *a, ...)
@@ -105,19 +105,19 @@ declare 26 {
int TclBN_mp_lshd(mp_int *a, int shift)
}
declare 27 {
int TclBN_mp_mod(mp_int *a, mp_int *b, mp_int *r)
int TclBN_mp_mod(const mp_int *a, const mp_int *b, mp_int *r)
}
declare 28 {
int TclBN_mp_mod_2d(const mp_int *a, int b, mp_int *r)
}
declare 29 {
int TclBN_mp_mul(mp_int *a, mp_int *b, mp_int *p)
int TclBN_mp_mul(const mp_int *a, const mp_int *b, mp_int *p)
}
declare 30 {
int TclBN_mp_mul_d(mp_int *a, mp_digit b, mp_int *p)
int TclBN_mp_mul_d(const mp_int *a, mp_digit b, mp_int *p)
}
declare 31 {
int TclBN_mp_mul_2(mp_int *a, mp_int *p)
int TclBN_mp_mul_2(const mp_int *a, mp_int *p)
}
declare 32 {
int TclBN_mp_mul_2d(const mp_int *a, int d, mp_int *p)
@@ -126,10 +126,10 @@ declare 33 {
int TclBN_mp_neg(const mp_int *a, mp_int *b)
}
declare 34 {
int TclBN_mp_or(mp_int *a, mp_int *b, mp_int *c)
int TclBN_mp_or(const mp_int *a, const mp_int *b, mp_int *c)
}
declare 35 {
int TclBN_mp_radix_size(mp_int *a, int radix, int *size)
int TclBN_mp_radix_size(const mp_int *a, int radix, int *size)
}
declare 36 {
int TclBN_mp_read_radix(mp_int *a, const char *str, int radix)
@@ -144,32 +144,32 @@ declare 39 {
void TclBN_mp_set(mp_int *a, mp_digit b)
}
declare 40 {
int TclBN_mp_sqr(mp_int *a, mp_int *b)
int TclBN_mp_sqr(const mp_int *a, mp_int *b)
}
declare 41 {
int TclBN_mp_sqrt(mp_int *a, mp_int *b)
int TclBN_mp_sqrt(const mp_int *a, mp_int *b)
}
declare 42 {
int TclBN_mp_sub(mp_int *a, mp_int *b, mp_int *c)
int TclBN_mp_sub(const mp_int *a, const mp_int *b, mp_int *c)
}
declare 43 {
int TclBN_mp_sub_d(mp_int *a, mp_digit b, mp_int *c)
int TclBN_mp_sub_d(const mp_int *a, mp_digit b, mp_int *c)
}
declare 44 {
int TclBN_mp_to_unsigned_bin(mp_int *a, unsigned char *b)
int TclBN_mp_to_unsigned_bin(const mp_int *a, unsigned char *b)
}
declare 45 {
int TclBN_mp_to_unsigned_bin_n(mp_int *a, unsigned char *b,
int TclBN_mp_to_unsigned_bin_n(const mp_int *a, unsigned char *b,
unsigned long *outlen)
}
declare 46 {
int TclBN_mp_toradix_n(mp_int *a, char *str, int radix, int maxlen)
int TclBN_mp_toradix_n(const mp_int *a, char *str, int radix, int maxlen)
}
declare 47 {
int TclBN_mp_unsigned_bin_size(mp_int *a)
int TclBN_mp_unsigned_bin_size(const mp_int *a)
}
declare 48 {
int TclBN_mp_xor(mp_int *a, mp_int *b, mp_int *c)
int TclBN_mp_xor(const mp_int *a, const mp_int *b, mp_int *c)
}
declare 49 {
void TclBN_mp_zero(mp_int *a)
@@ -182,34 +182,34 @@ declare 50 {
void TclBN_reverse(unsigned char *s, int len)
}
declare 51 {
int TclBN_fast_s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs)
int TclBN_fast_s_mp_mul_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs)
}
declare 52 {
int TclBN_fast_s_mp_sqr(mp_int *a, mp_int *b)
int TclBN_fast_s_mp_sqr(const mp_int *a, mp_int *b)
}
declare 53 {
int TclBN_mp_karatsuba_mul(mp_int *a, mp_int *b, mp_int *c)
int TclBN_mp_karatsuba_mul(const mp_int *a, const mp_int *b, mp_int *c)
}
declare 54 {
int TclBN_mp_karatsuba_sqr(mp_int *a, mp_int *b)
int TclBN_mp_karatsuba_sqr(const mp_int *a, mp_int *b)
}
declare 55 {
int TclBN_mp_toom_mul(mp_int *a, mp_int *b, mp_int *c)
int TclBN_mp_toom_mul(const mp_int *a, const mp_int *b, mp_int *c)
}
declare 56 {
int TclBN_mp_toom_sqr(mp_int *a, mp_int *b)
int TclBN_mp_toom_sqr(const mp_int *a, mp_int *b)
}
declare 57 {
int TclBN_s_mp_add(mp_int *a, mp_int *b, mp_int *c)
int TclBN_s_mp_add(const mp_int *a, const mp_int *b, mp_int *c)
}
declare 58 {
int TclBN_s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs)
int TclBN_s_mp_mul_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs)
}
declare 59 {
int TclBN_s_mp_sqr(mp_int *a, mp_int *b)
int TclBN_s_mp_sqr(const mp_int *a, mp_int *b)
}
declare 60 {
int TclBN_s_mp_sub(mp_int *a, mp_int *b, mp_int *c)
int TclBN_s_mp_sub(const mp_int *a, const mp_int *b, mp_int *c)
}
declare 61 {
int TclBN_mp_init_set_int(mp_int *a, unsigned long i)
@@ -233,6 +233,11 @@ declare 66 {
void TclBNInitBignumFromWideUInt(mp_int *bignum, Tcl_WideUInt initVal)
}
# Added in libtommath 1.0
declare 67 {
int TclBN_mp_expt_d_ex(const mp_int *a, mp_digit b, mp_int *c, int fast)
}
# Local Variables:
# mode: tcl
# End:
+229 -233
View File
@@ -9,8 +9,6 @@
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
*/
#ifndef BN_H_
#define BN_H_
@@ -22,32 +20,25 @@
#ifndef MIN
# define MIN(x,y) ((x)<(y)?(x):(y))
#endif
#ifndef MAX
# define MAX(x,y) ((x)>(y)?(x):(y))
#endif
#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
/* MS Visual C++ doesn't have a 128bit type for words, so fall back to 32bit MPI's (where words are 64bit) */
#if defined(_MSC_VER) || defined(__LLP64__) || defined(__e2k__) || defined(__LCC__)
# define MP_32BIT
#endif
/* detect 64-bit mode if possible */
#if defined(NEVER) /* 128-bit ints fail in too many places */
# if !(defined(MP_64BIT) && defined(MP_16BIT) && defined(MP_8BIT))
# define MP_64BIT
#if defined(NEVER)
# if !(defined(MP_32BIT) || defined(MP_16BIT) || defined(MP_8BIT))
# if defined(__GNUC__)
/* we support 128bit integers only via: __attribute__((mode(TI))) */
# define MP_64BIT
# else
/* otherwise we fall back to MP_32BIT even on 64bit platforms */
# define MP_32BIT
# endif
# endif
#endif
@@ -61,83 +52,67 @@ extern "C" {
*/
#ifdef MP_8BIT
#ifndef MP_DIGIT_DECLARED
typedef unsigned char mp_digit;
typedef unsigned char mp_digit;
#define MP_DIGIT_DECLARED
#endif
typedef unsigned short mp_word;
#ifndef MP_WORD_DECLARED
typedef unsigned short mp_word;
#define MP_WORD_DECLARED
#endif
# 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)
#ifndef MP_DIGIT_DECLARED
typedef unsigned short mp_digit;
typedef unsigned short mp_digit;
#define MP_DIGIT_DECLARED
#endif
typedef unsigned long mp_word;
#ifndef MP_WORD_DECLARED
typedef unsigned int mp_word;
#define MP_WORD_DECLARED
#endif
# 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
/* for GCC only on supported platforms */
#ifndef MP_DIGIT_DECLARED
typedef unsigned long mp_digit;
typedef unsigned long long mp_digit;
#define MP_DIGIT_DECLARED
#endif
typedef unsigned long mp_word __attribute__ ((mode(TI)));
# define DIGIT_BIT 60
typedef unsigned long mp_word __attribute__((mode(TI)));
# define DIGIT_BIT 60
#else
/* this is the default case, 28-bit digits */
/* this is to make porting into LibTomCrypt easier :-) */
#ifndef CRYPT
# if defined(_MSC_VER) || defined(__BORLANDC__)
typedef unsigned __int64 ulong64;
typedef signed __int64 long64;
# else
typedef unsigned long long ulong64;
typedef signed long long long64;
# endif
#endif
/* this is the default case, 28-bit digits */
/* this is to make porting into LibTomCrypt easier :-) */
#ifndef MP_DIGIT_DECLARED
typedef unsigned int mp_digit;
typedef unsigned int mp_digit;
#define MP_DIGIT_DECLARED
#endif
typedef ulong64 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
#ifndef MP_WORD_DECLARED
typedef unsigned long long mp_word;
#define MP_WORD_DECLARED
#endif
/* define heap macros */
#if 0 /* these are macros in tclTomMathDecls.h */
#ifndef CRYPT
/* default to libc stuff */
# ifndef XMALLOC
# define XMALLOC malloc
# define XFREE free
# define XREALLOC realloc
# 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
# 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
#endif
/* otherwise the bits per digit is calculated automatically from the size of a mp_digit */
#ifndef DIGIT_BIT
# define DIGIT_BIT ((int)((CHAR_BIT * sizeof(mp_digit) - 1))) /* bits per digit */
# define DIGIT_BIT (((CHAR_BIT * MP_SIZEOF_MP_DIGIT) - 1)) /* bits per digit */
typedef unsigned long mp_min_u32;
#else
typedef mp_digit mp_min_u32;
#endif
#define MP_DIGIT_BIT DIGIT_BIT
@@ -170,9 +145,9 @@ typedef int mp_err;
/* you'll have to tune these... */
#if defined(BUILD_tcl) || !defined(_WIN32)
MODULE_SCOPE int KARATSUBA_MUL_CUTOFF,
KARATSUBA_SQR_CUTOFF,
TOOM_MUL_CUTOFF,
TOOM_SQR_CUTOFF;
KARATSUBA_SQR_CUTOFF,
TOOM_MUL_CUTOFF,
TOOM_SQR_CUTOFF;
#endif
/* define this to use lower memory usage routines (exptmods mostly) */
@@ -180,15 +155,15 @@ MODULE_SCOPE int KARATSUBA_MUL_CUTOFF,
/* 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
# 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))
#define MP_WARRAY (1u << (((sizeof(mp_word) * CHAR_BIT) - (2 * DIGIT_BIT)) + 1))
/* the infamous mp_int structure */
#ifndef MP_INT_DECLARED
@@ -196,22 +171,20 @@ MODULE_SCOPE int KARATSUBA_MUL_CUTOFF,
typedef struct mp_int mp_int;
#endif
struct mp_int {
int used, alloc, sign;
mp_digit *dp;
int used, alloc, sign;
mp_digit *dp;
};
/* 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)
#define USED(m) ((m)->used)
#define DIGIT(m, k) ((m)->dp[(k)])
#define SIGN(m) ((m)->sign)
/* error code to char* string */
/*
char *mp_error_to_string(int code);
*/
const char *mp_error_to_string(int code);
/* ---> init and deinit bignum functions <--- */
/* init a bignum */
@@ -256,8 +229,9 @@ 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] & 1) == 0)) ? MP_YES : MP_NO)
#define mp_isodd(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 1)) ? 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 */
/*
@@ -274,17 +248,39 @@ void mp_set(mp_int *a, mp_digit b);
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);
/*
unsigned long mp_get_int(const mp_int *a);
*/
/* get a platform dependent unsigned long value */
/*
unsigned long mp_get_long(const mp_int *a);
*/
/* get a platform dependent unsigned long long value */
/*
unsigned long long mp_get_long_long(const mp_int *a);
*/
/* initialize and set a digit */
/*
int mp_init_set (mp_int * a, mp_digit b);
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);
int mp_init_set_int(mp_int *a, unsigned long b);
*/
/* copy, b = a */
@@ -294,7 +290,7 @@ int mp_copy(const mp_int *a, mp_int *b);
/* inits and copies, a = b */
/*
int mp_init_copy(mp_int *a, mp_int *b);
int mp_init_copy(mp_int *a, const mp_int *b);
*/
/* trim unused digits */
@@ -302,6 +298,16 @@ int mp_init_copy(mp_int *a, mp_int *b);
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, const mp_int *op);
*/
/* ---> digit manipulation <--- */
/* right shift by "b" digits */
@@ -314,27 +320,27 @@ void mp_rshd(mp_int *a, int b);
int mp_lshd(mp_int *a, int b);
*/
/* c = a / 2**b */
/* c = a / 2**b, implemented as c = a >> b */
/*
int mp_div_2d(const mp_int *a, int b, mp_int *c, mp_int *d);
*/
/* b = a/2 */
/*
int mp_div_2(mp_int *a, mp_int *b);
int mp_div_2(const mp_int *a, mp_int *b);
*/
/* c = a * 2**b */
/* c = a * 2**b, implemented as c = a << b */
/*
int mp_mul_2d(const mp_int *a, int b, mp_int *c);
*/
/* b = a*2 */
/*
int mp_mul_2(mp_int *a, mp_int *b);
int mp_mul_2(const mp_int *a, mp_int *b);
*/
/* c = a mod 2**d */
/* c = a mod 2**b */
/*
int mp_mod_2d(const mp_int *a, int b, mp_int *c);
*/
@@ -356,24 +362,57 @@ int mp_cnt_lsb(const mp_int *a);
int mp_rand(mp_int *a, int digits);
*/
#ifdef MP_PRNG_ENABLE_LTM_RNG
/* as last resort we will fall back to libtomcrypt's rng_get_bytes()
* in case you don't use libtomcrypt or use it w/o rng_get_bytes()
* you have to implement it somewhere else, as it's required */
extern unsigned long (*ltm_rng)(unsigned char *out, unsigned long outlen, void (*callback)(void));
extern void (*ltm_rng_callback)(void);
#endif
/* ---> binary operations <--- */
/* c = a XOR b */
/*
int mp_xor(mp_int *a, mp_int *b, mp_int *c);
int mp_xor(const mp_int *a, const mp_int *b, mp_int *c);
*/
/* c = a OR b */
/*
int mp_or(mp_int *a, mp_int *b, mp_int *c);
int mp_or(const mp_int *a, const mp_int *b, mp_int *c);
*/
/* c = a AND b */
/*
int mp_and(mp_int *a, mp_int *b, mp_int *c);
int mp_and(const mp_int *a, const mp_int *b, mp_int *c);
*/
/* c = a XOR b (two complement) */
/*
int mp_tc_xor(const mp_int *a, const mp_int *b, mp_int *c);
*/
/* c = a OR b (two complement) */
/*
int mp_tc_or(const mp_int *a, const mp_int *b, mp_int *c);
*/
/* c = a AND b (two complement) */
/*
int mp_tc_and(const mp_int *a, const mp_int *b, mp_int *c);
*/
/* right shift (two complement) */
/*
int mp_tc_div_2d(const mp_int *a, int b, mp_int *c);
*/
/* ---> Basic arithmetic <--- */
/* b = ~a */
/*
int mp_complement(const mp_int *a, mp_int *b);
*/
/* b = -a */
/*
int mp_neg(const mp_int *a, mp_int *b);
@@ -381,7 +420,7 @@ int mp_neg(const mp_int *a, mp_int *b);
/* b = |a| */
/*
int mp_abs(mp_int *a, mp_int *b);
int mp_abs(const mp_int *a, mp_int *b);
*/
/* compare a to b */
@@ -396,32 +435,32 @@ int mp_cmp_mag(const mp_int *a, const mp_int *b);
/* c = a + b */
/*
int mp_add(mp_int *a, mp_int *b, mp_int *c);
int mp_add(const mp_int *a, const mp_int *b, mp_int *c);
*/
/* c = a - b */
/*
int mp_sub(mp_int *a, mp_int *b, mp_int *c);
int mp_sub(const mp_int *a, const mp_int *b, mp_int *c);
*/
/* c = a * b */
/*
int mp_mul(mp_int *a, mp_int *b, mp_int *c);
int mp_mul(const mp_int *a, const mp_int *b, mp_int *c);
*/
/* b = a*a */
/*
int mp_sqr(mp_int *a, mp_int *b);
int mp_sqr(const 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);
int mp_div(const mp_int *a, const 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);
int mp_mod(const mp_int *a, const mp_int *b, mp_int *c);
*/
/* ---> single digit functions <--- */
@@ -433,79 +472,82 @@ int mp_cmp_d(const mp_int *a, mp_digit b);
/* c = a + b */
/*
int mp_add_d(mp_int *a, mp_digit b, mp_int *c);
int mp_add_d(const 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);
int mp_sub_d(const 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);
int mp_mul_d(const 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);
int mp_div_d(const 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);
int mp_div_3(const 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(const mp_int *a, mp_digit b, mp_int *c);
*/
/*
int mp_expt_d_ex(const 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);
int mp_mod_d(const 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);
int mp_addmod(const mp_int *a, const mp_int *b, const 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);
int mp_submod(const mp_int *a, const mp_int *b, const 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);
int mp_mulmod(const mp_int *a, const mp_int *b, const mp_int *c, mp_int *d);
*/
/* c = a * a (mod b) */
/*
int mp_sqrmod(mp_int *a, mp_int *b, mp_int *c);
int mp_sqrmod(const mp_int *a, const mp_int *b, mp_int *c);
*/
/* c = 1/a (mod b) */
/*
int mp_invmod(mp_int *a, mp_int *b, mp_int *c);
int mp_invmod(const mp_int *a, const mp_int *b, mp_int *c);
*/
/* c = (a, b) */
/*
int mp_gcd(mp_int *a, mp_int *b, mp_int *c);
int mp_gcd(const mp_int *a, const 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);
int mp_exteuclid(const mp_int *a, const 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);
int mp_lcm(const mp_int *a, const mp_int *b, mp_int *c);
*/
/* finds one of the b'th root of a, such that |c|**b <= |a|
@@ -513,136 +555,144 @@ int mp_lcm(mp_int *a, mp_int *b, mp_int *c);
* 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(const mp_int *a, mp_digit b, mp_int *c);
*/
/*
int mp_n_root_ex(const mp_int *a, mp_digit b, mp_int *c, int fast);
*/
/* special sqrt algo */
/*
int mp_sqrt(mp_int *arg, mp_int *ret);
int mp_sqrt(const mp_int *arg, mp_int *ret);
*/
/* special sqrt (mod prime) */
/*
int mp_sqrtmod_prime(const mp_int *n, const mp_int *prime, mp_int *ret);
*/
/* is number a square? */
/*
int mp_is_square(mp_int *arg, int *ret);
int mp_is_square(const 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);
int mp_jacobi(const mp_int *a, const 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);
int mp_reduce_setup(mp_int *a, const 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].
* Assumes that 0 < x <= m*m, note if 0 > x > -(m*m) then you can merely
* compute the reduction as -1 * mp_reduce(mp_abs(x)) [pseudo code].
*/
/*
int mp_reduce(mp_int *a, mp_int *b, mp_int *c);
int mp_reduce(mp_int *x, const mp_int *m, const mp_int *mu);
*/
/* setups the montgomery reduction */
/*
int mp_montgomery_setup(mp_int *a, mp_digit *mp);
int mp_montgomery_setup(const mp_int *n, mp_digit *rho);
*/
/* 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);
int mp_montgomery_calc_normalization(mp_int *a, const 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);
int mp_montgomery_reduce(mp_int *x, const mp_int *n, mp_digit rho);
*/
/* returns 1 if a is a valid DR modulus */
/*
int mp_dr_is_modulus(mp_int *a);
int mp_dr_is_modulus(const mp_int *a);
*/
/* sets the value of "d" required for mp_dr_reduce */
/*
void mp_dr_setup(mp_int *a, mp_digit *d);
void mp_dr_setup(const mp_int *a, mp_digit *d);
*/
/* reduces a modulo b using the Diminished Radix method */
/* reduces a modulo n using the Diminished Radix method */
/*
int mp_dr_reduce(mp_int *a, mp_int *b, mp_digit mp);
int mp_dr_reduce(mp_int *x, const mp_int *n, mp_digit k);
*/
/* returns true if a can be reduced with mp_reduce_2k */
/*
int mp_reduce_is_2k(mp_int *a);
int mp_reduce_is_2k(const mp_int *a);
*/
/* determines k value for 2k reduction */
/*
int mp_reduce_2k_setup(mp_int *a, mp_digit *d);
int mp_reduce_2k_setup(const 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);
int mp_reduce_2k(mp_int *a, const 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);
int mp_reduce_is_2k_l(const mp_int *a);
*/
/* determines k value for 2k reduction */
/*
int mp_reduce_2k_setup_l(mp_int *a, mp_int *d);
int mp_reduce_2k_setup_l(const 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);
int mp_reduce_2k_l(mp_int *a, const mp_int *n, const mp_int *d);
*/
/* d = a**b (mod c) */
/* Y = G**X (mod P) */
/*
int mp_exptmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
int mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y);
*/
/* ---> Primes <--- */
/* number of primes */
#ifdef MP_8BIT
# define PRIME_SIZE 31
# define PRIME_SIZE 31
#else
# define PRIME_SIZE 256
# define PRIME_SIZE 256
#endif
/* table of first PRIME_SIZE primes */
#if defined(BUILD_tcl) || !defined(_WIN32)
MODULE_SCOPE const mp_digit ltm_prime_tab[];
MODULE_SCOPE const mp_digit ltm_prime_tab[PRIME_SIZE];
#endif
/* result=1 if a is divisible by one of the first PRIME_SIZE primes */
/*
int mp_prime_is_divisible(mp_int *a, int *result);
int mp_prime_is_divisible(const 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);
int mp_prime_fermat(const mp_int *a, const 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);
int mp_prime_miller_rabin(const mp_int *a, const mp_int *b, int *result);
*/
/* This gives [for a given bit size] the number of trials required
@@ -660,7 +710,7 @@ int mp_prime_rabin_miller_trials(int size);
* Sets result to 1 if probably prime, 0 otherwise
*/
/*
int mp_prime_is_prime(mp_int *a, int t, int *result);
int mp_prime_is_prime(const mp_int *a, int t, int *result);
*/
/* finds the next prime after the number "a" using "t" trials
@@ -689,7 +739,6 @@ int mp_prime_next_prime(mp_int *a, int t, int bbs_style);
*
* 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_OFF - make the 2nd highest bit zero
* 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
@@ -707,50 +756,52 @@ int mp_count_bits(const mp_int *a);
*/
/*
int mp_unsigned_bin_size(mp_int *a);
int mp_unsigned_bin_size(const 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(const mp_int *a, unsigned char *b);
*/
/*
int mp_to_unsigned_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen);
int mp_to_unsigned_bin_n(const mp_int *a, unsigned char *b, unsigned long *outlen);
*/
/*
int mp_signed_bin_size(mp_int *a);
int mp_signed_bin_size(const 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(const mp_int *a, unsigned char *b);
*/
/*
int mp_to_signed_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen);
int mp_to_signed_bin_n(const 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(const mp_int *a, char *str, int radix);
*/
/*
int mp_toradix_n(mp_int * a, char *str, int radix, int maxlen);
int mp_toradix_n(const mp_int *a, char *str, int radix, int maxlen);
*/
/*
int mp_radix_size(mp_int *a, int radix, int *size);
int mp_radix_size(const 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);
int mp_fwrite(const 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)
@@ -764,69 +815,14 @@ int mp_fwrite(mp_int *a, int radix, FILE *stream);
#define mp_todecimal(M, S) mp_toradix((M), (S), 10)
#define mp_tohex(M, S) mp_toradix((M), (S), 16)
/* 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 *a, mp_int *m, mp_digit mp);
*/
/*
int mp_exptmod_fast(mp_int *G, mp_int *X, mp_int *P, mp_int *Y, int mode);
*/
/*
int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int mode);
*/
/*
void bn_reverse(unsigned char *s, int len);
*/
#if defined(BUILD_tcl) || !defined(_WIN32)
MODULE_SCOPE const char *mp_s_rmap;
#endif
#ifdef __cplusplus
}
#endif
#endif
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+98 -75
View File
@@ -73,6 +73,7 @@
#define mp_div_d TclBN_mp_div_d
#define mp_exch TclBN_mp_exch
#define mp_expt_d TclBN_mp_expt_d
#define mp_expt_d_ex TclBN_mp_expt_d_ex
#define mp_grow TclBN_mp_grow
#define mp_init TclBN_mp_init
#define mp_init_copy TclBN_mp_init_copy
@@ -94,7 +95,6 @@
#define mp_radix_size TclBN_mp_radix_size
#define mp_read_radix TclBN_mp_read_radix
#define mp_rshd TclBN_mp_rshd
#define mp_s_rmap TclBNMpSRmap
#define mp_set TclBN_mp_set
#define mp_set_int TclBN_mp_set_int
#define mp_shrink TclBN_mp_shrink
@@ -147,11 +147,14 @@ EXTERN int TclBN_epoch(void);
/* 1 */
EXTERN int TclBN_revision(void);
/* 2 */
EXTERN int TclBN_mp_add(mp_int *a, mp_int *b, mp_int *c);
EXTERN int TclBN_mp_add(const mp_int *a, const mp_int *b,
mp_int *c);
/* 3 */
EXTERN int TclBN_mp_add_d(mp_int *a, mp_digit b, mp_int *c);
EXTERN int TclBN_mp_add_d(const mp_int *a, mp_digit b,
mp_int *c);
/* 4 */
EXTERN int TclBN_mp_and(mp_int *a, mp_int *b, mp_int *c);
EXTERN int TclBN_mp_and(const mp_int *a, const mp_int *b,
mp_int *c);
/* 5 */
EXTERN void TclBN_mp_clamp(mp_int *a);
/* 6 */
@@ -169,28 +172,30 @@ EXTERN int TclBN_mp_copy(const mp_int *a, mp_int *b);
/* 12 */
EXTERN int TclBN_mp_count_bits(const mp_int *a);
/* 13 */
EXTERN int TclBN_mp_div(mp_int *a, mp_int *b, mp_int *q,
mp_int *r);
EXTERN int TclBN_mp_div(const mp_int *a, const mp_int *b,
mp_int *q, mp_int *r);
/* 14 */
EXTERN int TclBN_mp_div_d(mp_int *a, mp_digit b, mp_int *q,
mp_digit *r);
EXTERN int TclBN_mp_div_d(const mp_int *a, mp_digit b,
mp_int *q, mp_digit *r);
/* 15 */
EXTERN int TclBN_mp_div_2(mp_int *a, mp_int *q);
EXTERN int TclBN_mp_div_2(const mp_int *a, mp_int *q);
/* 16 */
EXTERN int TclBN_mp_div_2d(const mp_int *a, int b, mp_int *q,
mp_int *r);
/* 17 */
EXTERN int TclBN_mp_div_3(mp_int *a, mp_int *q, mp_digit *r);
EXTERN int TclBN_mp_div_3(const mp_int *a, mp_int *q,
mp_digit *r);
/* 18 */
EXTERN void TclBN_mp_exch(mp_int *a, mp_int *b);
/* 19 */
EXTERN int TclBN_mp_expt_d(mp_int *a, mp_digit b, mp_int *c);
EXTERN int TclBN_mp_expt_d(const mp_int *a, mp_digit b,
mp_int *c);
/* 20 */
EXTERN int TclBN_mp_grow(mp_int *a, int size);
/* 21 */
EXTERN int TclBN_mp_init(mp_int *a);
/* 22 */
EXTERN int TclBN_mp_init_copy(mp_int *a, mp_int *b);
EXTERN int TclBN_mp_init_copy(mp_int *a, const mp_int *b);
/* 23 */
EXTERN int TclBN_mp_init_multi(mp_int *a, ...);
/* 24 */
@@ -200,23 +205,28 @@ EXTERN int TclBN_mp_init_size(mp_int *a, int size);
/* 26 */
EXTERN int TclBN_mp_lshd(mp_int *a, int shift);
/* 27 */
EXTERN int TclBN_mp_mod(mp_int *a, mp_int *b, mp_int *r);
EXTERN int TclBN_mp_mod(const mp_int *a, const mp_int *b,
mp_int *r);
/* 28 */
EXTERN int TclBN_mp_mod_2d(const mp_int *a, int b, mp_int *r);
/* 29 */
EXTERN int TclBN_mp_mul(mp_int *a, mp_int *b, mp_int *p);
EXTERN int TclBN_mp_mul(const mp_int *a, const mp_int *b,
mp_int *p);
/* 30 */
EXTERN int TclBN_mp_mul_d(mp_int *a, mp_digit b, mp_int *p);
EXTERN int TclBN_mp_mul_d(const mp_int *a, mp_digit b,
mp_int *p);
/* 31 */
EXTERN int TclBN_mp_mul_2(mp_int *a, mp_int *p);
EXTERN int TclBN_mp_mul_2(const mp_int *a, mp_int *p);
/* 32 */
EXTERN int TclBN_mp_mul_2d(const mp_int *a, int d, mp_int *p);
/* 33 */
EXTERN int TclBN_mp_neg(const mp_int *a, mp_int *b);
/* 34 */
EXTERN int TclBN_mp_or(mp_int *a, mp_int *b, mp_int *c);
EXTERN int TclBN_mp_or(const mp_int *a, const mp_int *b,
mp_int *c);
/* 35 */
EXTERN int TclBN_mp_radix_size(mp_int *a, int radix, int *size);
EXTERN int TclBN_mp_radix_size(const mp_int *a, int radix,
int *size);
/* 36 */
EXTERN int TclBN_mp_read_radix(mp_int *a, const char *str,
int radix);
@@ -227,52 +237,59 @@ EXTERN int TclBN_mp_shrink(mp_int *a);
/* 39 */
EXTERN void TclBN_mp_set(mp_int *a, mp_digit b);
/* 40 */
EXTERN int TclBN_mp_sqr(mp_int *a, mp_int *b);
EXTERN int TclBN_mp_sqr(const mp_int *a, mp_int *b);
/* 41 */
EXTERN int TclBN_mp_sqrt(mp_int *a, mp_int *b);
EXTERN int TclBN_mp_sqrt(const mp_int *a, mp_int *b);
/* 42 */
EXTERN int TclBN_mp_sub(mp_int *a, mp_int *b, mp_int *c);
EXTERN int TclBN_mp_sub(const mp_int *a, const mp_int *b,
mp_int *c);
/* 43 */
EXTERN int TclBN_mp_sub_d(mp_int *a, mp_digit b, mp_int *c);
EXTERN int TclBN_mp_sub_d(const mp_int *a, mp_digit b,
mp_int *c);
/* 44 */
EXTERN int TclBN_mp_to_unsigned_bin(mp_int *a, unsigned char *b);
EXTERN int TclBN_mp_to_unsigned_bin(const mp_int *a,
unsigned char *b);
/* 45 */
EXTERN int TclBN_mp_to_unsigned_bin_n(mp_int *a,
EXTERN int TclBN_mp_to_unsigned_bin_n(const mp_int *a,
unsigned char *b, unsigned long *outlen);
/* 46 */
EXTERN int TclBN_mp_toradix_n(mp_int *a, char *str, int radix,
int maxlen);
EXTERN int TclBN_mp_toradix_n(const mp_int *a, char *str,
int radix, int maxlen);
/* 47 */
EXTERN int TclBN_mp_unsigned_bin_size(mp_int *a);
EXTERN int TclBN_mp_unsigned_bin_size(const mp_int *a);
/* 48 */
EXTERN int TclBN_mp_xor(mp_int *a, mp_int *b, mp_int *c);
EXTERN int TclBN_mp_xor(const mp_int *a, const mp_int *b,
mp_int *c);
/* 49 */
EXTERN void TclBN_mp_zero(mp_int *a);
/* 50 */
EXTERN void TclBN_reverse(unsigned char *s, int len);
/* 51 */
EXTERN int TclBN_fast_s_mp_mul_digs(mp_int *a, mp_int *b,
mp_int *c, int digs);
EXTERN int TclBN_fast_s_mp_mul_digs(const mp_int *a,
const mp_int *b, mp_int *c, int digs);
/* 52 */
EXTERN int TclBN_fast_s_mp_sqr(mp_int *a, mp_int *b);
EXTERN int TclBN_fast_s_mp_sqr(const mp_int *a, mp_int *b);
/* 53 */
EXTERN int TclBN_mp_karatsuba_mul(mp_int *a, mp_int *b,
mp_int *c);
EXTERN int TclBN_mp_karatsuba_mul(const mp_int *a,
const mp_int *b, mp_int *c);
/* 54 */
EXTERN int TclBN_mp_karatsuba_sqr(mp_int *a, mp_int *b);
EXTERN int TclBN_mp_karatsuba_sqr(const mp_int *a, mp_int *b);
/* 55 */
EXTERN int TclBN_mp_toom_mul(mp_int *a, mp_int *b, mp_int *c);
EXTERN int TclBN_mp_toom_mul(const mp_int *a, const mp_int *b,
mp_int *c);
/* 56 */
EXTERN int TclBN_mp_toom_sqr(mp_int *a, mp_int *b);
EXTERN int TclBN_mp_toom_sqr(const mp_int *a, mp_int *b);
/* 57 */
EXTERN int TclBN_s_mp_add(mp_int *a, mp_int *b, mp_int *c);
EXTERN int TclBN_s_mp_add(const mp_int *a, const mp_int *b,
mp_int *c);
/* 58 */
EXTERN int TclBN_s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c,
int digs);
EXTERN int TclBN_s_mp_mul_digs(const mp_int *a, const mp_int *b,
mp_int *c, int digs);
/* 59 */
EXTERN int TclBN_s_mp_sqr(mp_int *a, mp_int *b);
EXTERN int TclBN_s_mp_sqr(const mp_int *a, mp_int *b);
/* 60 */
EXTERN int TclBN_s_mp_sub(mp_int *a, mp_int *b, mp_int *c);
EXTERN int TclBN_s_mp_sub(const mp_int *a, const mp_int *b,
mp_int *c);
/* 61 */
EXTERN int TclBN_mp_init_set_int(mp_int *a, unsigned long i);
/* 62 */
@@ -287,6 +304,9 @@ EXTERN void TclBNInitBignumFromWideInt(mp_int *bignum,
/* 66 */
EXTERN void TclBNInitBignumFromWideUInt(mp_int *bignum,
Tcl_WideUInt initVal);
/* 67 */
EXTERN int TclBN_mp_expt_d_ex(const mp_int *a, mp_digit b,
mp_int *c, int fast);
typedef struct TclTomMathStubs {
int magic;
@@ -294,9 +314,9 @@ typedef struct TclTomMathStubs {
int (*tclBN_epoch) (void); /* 0 */
int (*tclBN_revision) (void); /* 1 */
int (*tclBN_mp_add) (mp_int *a, mp_int *b, mp_int *c); /* 2 */
int (*tclBN_mp_add_d) (mp_int *a, mp_digit b, mp_int *c); /* 3 */
int (*tclBN_mp_and) (mp_int *a, mp_int *b, mp_int *c); /* 4 */
int (*tclBN_mp_add) (const mp_int *a, const mp_int *b, mp_int *c); /* 2 */
int (*tclBN_mp_add_d) (const mp_int *a, mp_digit b, mp_int *c); /* 3 */
int (*tclBN_mp_and) (const mp_int *a, const mp_int *b, mp_int *c); /* 4 */
void (*tclBN_mp_clamp) (mp_int *a); /* 5 */
void (*tclBN_mp_clear) (mp_int *a); /* 6 */
void (*tclBN_mp_clear_multi) (mp_int *a, ...); /* 7 */
@@ -305,60 +325,61 @@ typedef struct TclTomMathStubs {
int (*tclBN_mp_cmp_mag) (const mp_int *a, const mp_int *b); /* 10 */
int (*tclBN_mp_copy) (const mp_int *a, mp_int *b); /* 11 */
int (*tclBN_mp_count_bits) (const mp_int *a); /* 12 */
int (*tclBN_mp_div) (mp_int *a, mp_int *b, mp_int *q, mp_int *r); /* 13 */
int (*tclBN_mp_div_d) (mp_int *a, mp_digit b, mp_int *q, mp_digit *r); /* 14 */
int (*tclBN_mp_div_2) (mp_int *a, mp_int *q); /* 15 */
int (*tclBN_mp_div) (const mp_int *a, const mp_int *b, mp_int *q, mp_int *r); /* 13 */
int (*tclBN_mp_div_d) (const mp_int *a, mp_digit b, mp_int *q, mp_digit *r); /* 14 */
int (*tclBN_mp_div_2) (const mp_int *a, mp_int *q); /* 15 */
int (*tclBN_mp_div_2d) (const mp_int *a, int b, mp_int *q, mp_int *r); /* 16 */
int (*tclBN_mp_div_3) (mp_int *a, mp_int *q, mp_digit *r); /* 17 */
int (*tclBN_mp_div_3) (const mp_int *a, mp_int *q, mp_digit *r); /* 17 */
void (*tclBN_mp_exch) (mp_int *a, mp_int *b); /* 18 */
int (*tclBN_mp_expt_d) (mp_int *a, mp_digit b, mp_int *c); /* 19 */
int (*tclBN_mp_expt_d) (const mp_int *a, mp_digit b, mp_int *c); /* 19 */
int (*tclBN_mp_grow) (mp_int *a, int size); /* 20 */
int (*tclBN_mp_init) (mp_int *a); /* 21 */
int (*tclBN_mp_init_copy) (mp_int *a, mp_int *b); /* 22 */
int (*tclBN_mp_init_copy) (mp_int *a, const mp_int *b); /* 22 */
int (*tclBN_mp_init_multi) (mp_int *a, ...); /* 23 */
int (*tclBN_mp_init_set) (mp_int *a, mp_digit b); /* 24 */
int (*tclBN_mp_init_size) (mp_int *a, int size); /* 25 */
int (*tclBN_mp_lshd) (mp_int *a, int shift); /* 26 */
int (*tclBN_mp_mod) (mp_int *a, mp_int *b, mp_int *r); /* 27 */
int (*tclBN_mp_mod) (const mp_int *a, const mp_int *b, mp_int *r); /* 27 */
int (*tclBN_mp_mod_2d) (const mp_int *a, int b, mp_int *r); /* 28 */
int (*tclBN_mp_mul) (mp_int *a, mp_int *b, mp_int *p); /* 29 */
int (*tclBN_mp_mul_d) (mp_int *a, mp_digit b, mp_int *p); /* 30 */
int (*tclBN_mp_mul_2) (mp_int *a, mp_int *p); /* 31 */
int (*tclBN_mp_mul) (const mp_int *a, const mp_int *b, mp_int *p); /* 29 */
int (*tclBN_mp_mul_d) (const mp_int *a, mp_digit b, mp_int *p); /* 30 */
int (*tclBN_mp_mul_2) (const mp_int *a, mp_int *p); /* 31 */
int (*tclBN_mp_mul_2d) (const mp_int *a, int d, mp_int *p); /* 32 */
int (*tclBN_mp_neg) (const mp_int *a, mp_int *b); /* 33 */
int (*tclBN_mp_or) (mp_int *a, mp_int *b, mp_int *c); /* 34 */
int (*tclBN_mp_radix_size) (mp_int *a, int radix, int *size); /* 35 */
int (*tclBN_mp_or) (const mp_int *a, const mp_int *b, mp_int *c); /* 34 */
int (*tclBN_mp_radix_size) (const mp_int *a, int radix, int *size); /* 35 */
int (*tclBN_mp_read_radix) (mp_int *a, const char *str, int radix); /* 36 */
void (*tclBN_mp_rshd) (mp_int *a, int shift); /* 37 */
int (*tclBN_mp_shrink) (mp_int *a); /* 38 */
void (*tclBN_mp_set) (mp_int *a, mp_digit b); /* 39 */
int (*tclBN_mp_sqr) (mp_int *a, mp_int *b); /* 40 */
int (*tclBN_mp_sqrt) (mp_int *a, mp_int *b); /* 41 */
int (*tclBN_mp_sub) (mp_int *a, mp_int *b, mp_int *c); /* 42 */
int (*tclBN_mp_sub_d) (mp_int *a, mp_digit b, mp_int *c); /* 43 */
int (*tclBN_mp_to_unsigned_bin) (mp_int *a, unsigned char *b); /* 44 */
int (*tclBN_mp_to_unsigned_bin_n) (mp_int *a, unsigned char *b, unsigned long *outlen); /* 45 */
int (*tclBN_mp_toradix_n) (mp_int *a, char *str, int radix, int maxlen); /* 46 */
int (*tclBN_mp_unsigned_bin_size) (mp_int *a); /* 47 */
int (*tclBN_mp_xor) (mp_int *a, mp_int *b, mp_int *c); /* 48 */
int (*tclBN_mp_sqr) (const mp_int *a, mp_int *b); /* 40 */
int (*tclBN_mp_sqrt) (const mp_int *a, mp_int *b); /* 41 */
int (*tclBN_mp_sub) (const mp_int *a, const mp_int *b, mp_int *c); /* 42 */
int (*tclBN_mp_sub_d) (const mp_int *a, mp_digit b, mp_int *c); /* 43 */
int (*tclBN_mp_to_unsigned_bin) (const mp_int *a, unsigned char *b); /* 44 */
int (*tclBN_mp_to_unsigned_bin_n) (const mp_int *a, unsigned char *b, unsigned long *outlen); /* 45 */
int (*tclBN_mp_toradix_n) (const mp_int *a, char *str, int radix, int maxlen); /* 46 */
int (*tclBN_mp_unsigned_bin_size) (const mp_int *a); /* 47 */
int (*tclBN_mp_xor) (const mp_int *a, const mp_int *b, mp_int *c); /* 48 */
void (*tclBN_mp_zero) (mp_int *a); /* 49 */
void (*tclBN_reverse) (unsigned char *s, int len); /* 50 */
int (*tclBN_fast_s_mp_mul_digs) (mp_int *a, mp_int *b, mp_int *c, int digs); /* 51 */
int (*tclBN_fast_s_mp_sqr) (mp_int *a, mp_int *b); /* 52 */
int (*tclBN_mp_karatsuba_mul) (mp_int *a, mp_int *b, mp_int *c); /* 53 */
int (*tclBN_mp_karatsuba_sqr) (mp_int *a, mp_int *b); /* 54 */
int (*tclBN_mp_toom_mul) (mp_int *a, mp_int *b, mp_int *c); /* 55 */
int (*tclBN_mp_toom_sqr) (mp_int *a, mp_int *b); /* 56 */
int (*tclBN_s_mp_add) (mp_int *a, mp_int *b, mp_int *c); /* 57 */
int (*tclBN_s_mp_mul_digs) (mp_int *a, mp_int *b, mp_int *c, int digs); /* 58 */
int (*tclBN_s_mp_sqr) (mp_int *a, mp_int *b); /* 59 */
int (*tclBN_s_mp_sub) (mp_int *a, mp_int *b, mp_int *c); /* 60 */
int (*tclBN_fast_s_mp_mul_digs) (const mp_int *a, const mp_int *b, mp_int *c, int digs); /* 51 */
int (*tclBN_fast_s_mp_sqr) (const mp_int *a, mp_int *b); /* 52 */
int (*tclBN_mp_karatsuba_mul) (const mp_int *a, const mp_int *b, mp_int *c); /* 53 */
int (*tclBN_mp_karatsuba_sqr) (const mp_int *a, mp_int *b); /* 54 */
int (*tclBN_mp_toom_mul) (const mp_int *a, const mp_int *b, mp_int *c); /* 55 */
int (*tclBN_mp_toom_sqr) (const mp_int *a, mp_int *b); /* 56 */
int (*tclBN_s_mp_add) (const mp_int *a, const mp_int *b, mp_int *c); /* 57 */
int (*tclBN_s_mp_mul_digs) (const mp_int *a, const mp_int *b, mp_int *c, int digs); /* 58 */
int (*tclBN_s_mp_sqr) (const mp_int *a, mp_int *b); /* 59 */
int (*tclBN_s_mp_sub) (const mp_int *a, const mp_int *b, mp_int *c); /* 60 */
int (*tclBN_mp_init_set_int) (mp_int *a, unsigned long i); /* 61 */
int (*tclBN_mp_set_int) (mp_int *a, unsigned long i); /* 62 */
int (*tclBN_mp_cnt_lsb) (const mp_int *a); /* 63 */
void (*tclBNInitBignumFromLong) (mp_int *bignum, long initVal); /* 64 */
void (*tclBNInitBignumFromWideInt) (mp_int *bignum, Tcl_WideInt initVal); /* 65 */
void (*tclBNInitBignumFromWideUInt) (mp_int *bignum, Tcl_WideUInt initVal); /* 66 */
int (*tclBN_mp_expt_d_ex) (const mp_int *a, mp_digit b, mp_int *c, int fast); /* 67 */
} TclTomMathStubs;
extern const TclTomMathStubs *tclTomMathStubsPtr;
@@ -507,6 +528,8 @@ extern const TclTomMathStubs *tclTomMathStubsPtr;
(tclTomMathStubsPtr->tclBNInitBignumFromWideInt) /* 65 */
#define TclBNInitBignumFromWideUInt \
(tclTomMathStubsPtr->tclBNInitBignumFromWideUInt) /* 66 */
#define TclBN_mp_expt_d_ex \
(tclTomMathStubsPtr->tclBN_mp_expt_d_ex) /* 67 */
#endif /* defined(USE_TCL_STUBS) */
+4 -12
View File
@@ -537,9 +537,7 @@ TraceExecutionObjCmd(
Tcl_DeleteTrace(interp, tcmdPtr->stepTrace);
tcmdPtr->stepTrace = NULL;
if (tcmdPtr->startCmd != NULL) {
ckfree(tcmdPtr->startCmd);
}
ckfree(tcmdPtr->startCmd);
}
if (tcmdPtr->flags & TCL_TRACE_EXEC_IN_PROGRESS) {
/*
@@ -1349,9 +1347,7 @@ TraceCommandProc(
if (tcmdPtr->stepTrace != NULL) {
Tcl_DeleteTrace(interp, tcmdPtr->stepTrace);
tcmdPtr->stepTrace = NULL;
if (tcmdPtr->startCmd != NULL) {
ckfree(tcmdPtr->startCmd);
}
ckfree(tcmdPtr->startCmd);
}
if (tcmdPtr->flags & TCL_TRACE_EXEC_IN_PROGRESS) {
/*
@@ -1814,9 +1810,7 @@ TraceExecutionProc(
&& (strcmp(command, tcmdPtr->startCmd) == 0)) {
Tcl_DeleteTrace(interp, tcmdPtr->stepTrace);
tcmdPtr->stepTrace = NULL;
if (tcmdPtr->startCmd != NULL) {
ckfree(tcmdPtr->startCmd);
}
ckfree(tcmdPtr->startCmd);
}
/*
@@ -1941,9 +1935,7 @@ TraceExecutionProc(
if (tcmdPtr->stepTrace != NULL) {
Tcl_DeleteTrace(interp, tcmdPtr->stepTrace);
tcmdPtr->stepTrace = NULL;
if (tcmdPtr->startCmd != NULL) {
ckfree(tcmdPtr->startCmd);
}
ckfree(tcmdPtr->startCmd);
}
}
if (call) {
+867 -835
View File
File diff suppressed because it is too large Load Diff
+75 -66
View File
@@ -158,23 +158,22 @@ Tcl_UniCharToUtf(
if ((ch & 0xF800) == 0xD800) {
if (ch & 0x0400) {
/* Low surrogate */
if (((buf[0] & 0xF8) == 0xF0) && ((buf[1] & 0xC0) == 0x80)
&& ((buf[2] & 0xCF) == 0)) {
/* Previous Tcl_UniChar was a High surrogate, so combine */
buf[3] = (char) ((ch & 0x3F) | 0x80);
buf[2] |= (char) (((ch >> 6) & 0x0F) | 0x80);
return 4;
if (((buf[0] & 0xC0) == 0x80) && ((buf[1] & 0xCF) == 0)) {
/* Previous Tcl_UniChar was a high surrogate, so combine */
buf[2] = (char) ((ch & 0x3F) | 0x80);
buf[1] |= (char) (((ch >> 6) & 0x0F) | 0x80);
return 3;
}
/* Previous Tcl_UniChar was not a High surrogate, so just output */
/* Previous Tcl_UniChar was not a high surrogate, so just output */
} else {
/* High surrogate */
ch += 0x40;
/* Fill buffer with specific 3-byte (invalid) byte combination,
so following Low surrogate can recognize it and combine */
so following low surrogate can recognize it and combine */
buf[2] = (char) ((ch << 4) & 0x30);
buf[1] = (char) (((ch >> 2) & 0x3F) | 0x80);
buf[0] = (char) (((ch >> 8) & 0x07) | 0xF0);
return 0;
return 1;
}
}
#endif
@@ -190,11 +189,14 @@ Tcl_UniCharToUtf(
return 4;
}
} else if (ch == -1) {
if (((buf[0] & 0xF8) == 0xF0) && ((buf[1] & 0xC0) == 0x80)
&& ((buf[2] & 0xCF) == 0)) {
ch = 0xD7C0 + ((buf[0] & 0x07) << 8) + ((buf[1] & 0x3F) << 2)
+ ((buf[2] & 0x30) >> 4);
goto three;
if (((buf[0] & 0xC0) == 0x80) && ((buf[1] & 0xCF) == 0)
&& ((buf[-1] & 0xF8) == 0xF0)) {
ch = 0xD7C0 + ((buf[-1] & 0x07) << 8) + ((buf[0] & 0x3F) << 2)
+ ((buf[1] & 0x30) >> 4);
buf[1] = (char) ((ch | 0x80) & 0xBF);
buf[0] = (char) (((ch >> 6) | 0x80) & 0xBF);
buf[-1] = (char) ((ch >> 12) | 0xE0);
return 2;
}
#endif
}
@@ -298,7 +300,7 @@ Tcl_UtfToUniChar(
register Tcl_UniChar *chPtr)/* Filled with the Tcl_UniChar represented by
* the UTF-8 string. */
{
register int byte;
Tcl_UniChar byte;
/*
* Unroll 1 to 3 (or 4) byte UTF-8 sequences.
@@ -312,7 +314,21 @@ Tcl_UtfToUniChar(
* characters representing themselves.
*/
*chPtr = (Tcl_UniChar) byte;
#if TCL_UTF_MAX == 4
/* If *chPtr contains a high surrogate (produced by a previous
* Tcl_UtfToUniChar() call) and the next 3 bytes are UTF-8 continuation
* bytes, then we must produce a follow-up low surrogate. We only
* do that if the high surrogate matches the bits we encounter.
*/
if ((byte >= 0x80)
&& (((((byte - 0x10) << 2) & 0xFC) | 0xD800) == (*chPtr & 0xFCFC))
&& ((src[1] & 0xF0) == (((*chPtr << 4) & 0x30) | 0x80))
&& ((src[2] & 0xC0) == 0x80)) {
*chPtr = ((src[1] & 0x0F) << 6) + (src[2] & 0x3F) + 0xDC00;
return 3;
}
#endif
*chPtr = byte;
return 1;
} else if (byte < 0xE0) {
if ((src[1] & 0xC0) == 0x80) {
@@ -320,7 +336,7 @@ Tcl_UtfToUniChar(
* Two-byte-character lead-byte followed by a trail-byte.
*/
*chPtr = (Tcl_UniChar) (((byte & 0x1F) << 6) | (src[1] & 0x3F));
*chPtr = (((byte & 0x1F) << 6) | (src[1] & 0x3F));
if ((unsigned)(*chPtr - 1) >= (UNICODE_SELF - 1)) {
return 2;
}
@@ -336,7 +352,7 @@ Tcl_UtfToUniChar(
* Three-byte-character lead byte followed by two trail bytes.
*/
*chPtr = (Tcl_UniChar) (((byte & 0x0F) << 12)
*chPtr = (((byte & 0x0F) << 12)
| ((src[1] & 0x3F) << 6) | (src[2] & 0x3F));
if (*chPtr > 0x7FF) {
return 3;
@@ -355,26 +371,19 @@ Tcl_UtfToUniChar(
* Four-byte-character lead byte followed by three trail bytes.
*/
#if TCL_UTF_MAX == 4
Tcl_UniChar surrogate;
byte = (((byte & 0x07) << 18) | ((src[1] & 0x3F) << 12)
| ((src[2] & 0x3F) << 6) | (src[3] & 0x3F)) - 0x10000;
surrogate = (Tcl_UniChar) (0xD800 + (byte >> 10));
if (byte & 0x100000) {
Tcl_UniChar high = (((byte & 0x07) << 8) | ((src[1] & 0x3F) << 2)
| ((src[2] & 0x3F) >> 4)) - 0x40;
if (high >= 0x400) {
/* out of range, < 0x10000 or > 0x10ffff */
} else if (*chPtr != surrogate) {
/* produce high surrogate, but don't advance source pointer */
*chPtr = surrogate;
return 0;
} else {
/* produce low surrogate, and advance source pointer */
*chPtr = (Tcl_UniChar) (0xDC00 | (byte & 0x3FF));
return 4;
/* produce high surrogate, advance source pointer */
*chPtr = 0xD800 + high;
return 1;
}
#else
*chPtr = (Tcl_UniChar) (((byte & 0x07) << 18) | ((src[1] & 0x3F) << 12)
*chPtr = (((byte & 0x07) << 18) | ((src[1] & 0x3F) << 12)
| ((src[2] & 0x3F) << 6) | (src[3] & 0x3F));
if ((unsigned)(*chPtr - 0x10000) <= 0xFFFFF) {
if ((*chPtr - 0x10000) <= 0xFFFFF) {
return 4;
}
#endif
@@ -387,7 +396,7 @@ Tcl_UtfToUniChar(
}
#endif
*chPtr = (Tcl_UniChar) byte;
*chPtr = byte;
return 1;
}
@@ -578,8 +587,8 @@ Tcl_UtfFindFirst(
len = TclUtfToUniChar(src, &find);
fullchar = find;
#if TCL_UTF_MAX == 4
if (!len) {
len += TclUtfToUniChar(src, &find);
if ((ch >= 0xD800) && (len < 3)) {
len += TclUtfToUniChar(src + len, &find);
fullchar = (((fullchar & 0x3ff) << 10) | (find & 0x3ff)) + 0x10000;
}
#endif
@@ -626,8 +635,8 @@ Tcl_UtfFindLast(
len = TclUtfToUniChar(src, &find);
fullchar = find;
#if TCL_UTF_MAX == 4
if (!len) {
len += TclUtfToUniChar(src, &find);
if ((ch >= 0xD800) && (len < 3)) {
len += TclUtfToUniChar(src + len, &find);
fullchar = (((fullchar & 0x3ff) << 10) | (find & 0x3ff)) + 0x10000;
}
#endif
@@ -669,8 +678,8 @@ Tcl_UtfNext(
int len = TclUtfToUniChar(src, &ch);
#if TCL_UTF_MAX == 4
if (len == 0) {
len = TclUtfToUniChar(src, &ch);
if ((ch >= 0xD800) && (len < 3)) {
len += TclUtfToUniChar(src + len, &ch);
}
#endif
return src + len;
@@ -779,15 +788,15 @@ Tcl_UtfAtIndex(
register int index) /* The position of the desired character. */
{
Tcl_UniChar ch = 0;
int len = 1;
int len = 0;
while (index-- > 0) {
len = TclUtfToUniChar(src, &ch);
src += len;
}
#if TCL_UTF_MAX == 4
if (!len) {
/* Index points at character following High Surrogate */
if ((ch >= 0xD800) && (len < 3)) {
/* Index points at character following high Surrogate */
src += TclUtfToUniChar(src, &ch);
}
#endif
@@ -871,7 +880,7 @@ Tcl_UtfToUpper(
{
Tcl_UniChar ch = 0, upChar;
char *src, *dst;
int bytes;
int len;
/*
* Iterate over the string until we hit the terminating null.
@@ -879,7 +888,7 @@ Tcl_UtfToUpper(
src = dst = str;
while (*src) {
bytes = TclUtfToUniChar(src, &ch);
len = TclUtfToUniChar(src, &ch);
upChar = Tcl_UniCharToUpper(ch);
/*
@@ -888,13 +897,13 @@ Tcl_UtfToUpper(
* char to dst if its size is <= the original char.
*/
if (bytes < UtfCount(upChar)) {
memcpy(dst, src, (size_t) bytes);
dst += bytes;
if (len < UtfCount(upChar)) {
memcpy(dst, src, len);
dst += len;
} else {
dst += Tcl_UniCharToUtf(upChar, dst);
}
src += bytes;
src += len;
}
*dst = '\0';
return (dst - str);
@@ -924,7 +933,7 @@ Tcl_UtfToLower(
{
Tcl_UniChar ch = 0, lowChar;
char *src, *dst;
int bytes;
int len;
/*
* Iterate over the string until we hit the terminating null.
@@ -932,7 +941,7 @@ Tcl_UtfToLower(
src = dst = str;
while (*src) {
bytes = TclUtfToUniChar(src, &ch);
len = TclUtfToUniChar(src, &ch);
lowChar = Tcl_UniCharToLower(ch);
/*
@@ -941,13 +950,13 @@ Tcl_UtfToLower(
* char to dst if its size is <= the original char.
*/
if (bytes < UtfCount(lowChar)) {
memcpy(dst, src, (size_t) bytes);
dst += bytes;
if (len < UtfCount(lowChar)) {
memcpy(dst, src, len);
dst += len;
} else {
dst += Tcl_UniCharToUtf(lowChar, dst);
}
src += bytes;
src += len;
}
*dst = '\0';
return (dst - str);
@@ -978,7 +987,7 @@ Tcl_UtfToTitle(
{
Tcl_UniChar ch = 0, titleChar, lowChar;
char *src, *dst;
int bytes;
int len;
/*
* Capitalize the first character and then lowercase the rest of the
@@ -988,32 +997,32 @@ Tcl_UtfToTitle(
src = dst = str;
if (*src) {
bytes = TclUtfToUniChar(src, &ch);
len = TclUtfToUniChar(src, &ch);
titleChar = Tcl_UniCharToTitle(ch);
if (bytes < UtfCount(titleChar)) {
memcpy(dst, src, (size_t) bytes);
dst += bytes;
if (len < UtfCount(titleChar)) {
memcpy(dst, src, len);
dst += len;
} else {
dst += Tcl_UniCharToUtf(titleChar, dst);
}
src += bytes;
src += len;
}
while (*src) {
bytes = TclUtfToUniChar(src, &ch);
len = TclUtfToUniChar(src, &ch);
lowChar = ch;
/* Special exception for Georgian Asomtavruli chars, no titlecase. */
if ((unsigned)(lowChar - 0x1C90) >= 0x30) {
lowChar = Tcl_UniCharToLower(lowChar);
}
if (bytes < UtfCount(lowChar)) {
memcpy(dst, src, (size_t) bytes);
dst += bytes;
if (len < UtfCount(lowChar)) {
memcpy(dst, src, len);
dst += len;
} else {
dst += Tcl_UniCharToUtf(lowChar, dst);
}
src += bytes;
src += len;
}
*dst = '\0';
return (dst - str);
+1 -1
View File
@@ -1649,7 +1649,7 @@ Tcl_Backslash(
int *readPtr) /* Fill in with number of characters read from
* src, unless NULL. */
{
char buf[TCL_UTF_MAX];
char buf[TCL_UTF_MAX] = "";
Tcl_UniChar ch = 0;
Tcl_UtfBackslash(src, readPtr, buf);
+1 -1
View File
@@ -1488,7 +1488,7 @@ Tcl_ZlibStreamGet(
count = 0;
for (i=0; i<listLen; i++) {
Tcl_ListObjIndex(NULL, zshPtr->outData, i, &itemObj);
itemPtr = Tcl_GetByteArrayFromObj(itemObj, &itemLen);
(void) Tcl_GetByteArrayFromObj(itemObj, &itemLen);
if (i == 0) {
count += itemLen - zshPtr->outPos;
} else {
+41 -1
View File
@@ -56,5 +56,45 @@ set TZData(:Africa/Casablanca) {
{1521943200 3600 1 +00}
{1526176800 0 0 +00}
{1529200800 3600 1 +00}
{1540598400 3600 0 +01}
{1540695600 3600 0 +01}
{1557021600 0 1 +01}
{1560045600 3600 0 +01}
{1587261600 0 1 +01}
{1590285600 3600 0 +01}
{1618106400 0 1 +01}
{1621130400 3600 0 +01}
{1648346400 0 1 +01}
{1651975200 3600 0 +01}
{1679191200 0 1 +01}
{1682215200 3600 0 +01}
{1710036000 0 1 +01}
{1713060000 3600 0 +01}
{1740276000 0 1 +01}
{1743904800 3600 0 +01}
{1771120800 0 1 +01}
{1774144800 3600 0 +01}
{1801965600 0 1 +01}
{1804989600 3600 0 +01}
{1832205600 0 1 +01}
{1835229600 3600 0 +01}
{1863050400 0 1 +01}
{1866074400 3600 0 +01}
{1893290400 0 1 +01}
{1896919200 3600 0 +01}
{1924135200 0 1 +01}
{1927159200 3600 0 +01}
{1954980000 0 1 +01}
{1958004000 3600 0 +01}
{1985220000 0 1 +01}
{1988848800 3600 0 +01}
{2016064800 0 1 +01}
{2019088800 3600 0 +01}
{2046304800 0 1 +01}
{2049933600 3600 0 +01}
{2077149600 0 1 +01}
{2080173600 3600 0 +01}
{2107994400 0 1 +01}
{2111018400 3600 0 +01}
{2138234400 0 1 +01}
{2141863200 3600 0 +01}
}
+41 -1
View File
@@ -45,5 +45,45 @@ set TZData(:Africa/El_Aaiun) {
{1521943200 3600 1 +00}
{1526176800 0 0 +00}
{1529200800 3600 1 +00}
{1540598400 3600 0 +01}
{1540695600 3600 0 +01}
{1557021600 0 1 +01}
{1560045600 3600 0 +01}
{1587261600 0 1 +01}
{1590285600 3600 0 +01}
{1618106400 0 1 +01}
{1621130400 3600 0 +01}
{1648346400 0 1 +01}
{1651975200 3600 0 +01}
{1679191200 0 1 +01}
{1682215200 3600 0 +01}
{1710036000 0 1 +01}
{1713060000 3600 0 +01}
{1740276000 0 1 +01}
{1743904800 3600 0 +01}
{1771120800 0 1 +01}
{1774144800 3600 0 +01}
{1801965600 0 1 +01}
{1804989600 3600 0 +01}
{1832205600 0 1 +01}
{1835229600 3600 0 +01}
{1863050400 0 1 +01}
{1866074400 3600 0 +01}
{1893290400 0 1 +01}
{1896919200 3600 0 +01}
{1924135200 0 1 +01}
{1927159200 3600 0 +01}
{1954980000 0 1 +01}
{1958004000 3600 0 +01}
{1985220000 0 1 +01}
{1988848800 3600 0 +01}
{2016064800 0 1 +01}
{2019088800 3600 0 +01}
{2046304800 0 1 +01}
{2049933600 3600 0 +01}
{2077149600 0 1 +01}
{2080173600 3600 0 +01}
{2107994400 0 1 +01}
{2111018400 3600 0 +01}
{2138234400 0 1 +01}
{2141863200 3600 0 +01}
}
+1
View File
@@ -5,4 +5,5 @@ set TZData(:Africa/Sao_Tome) {
{-2713912016 -2205 0 LMT}
{-1830384000 0 0 GMT}
{1514768400 3600 0 WAT}
{1546304400 0 0 GMT}
}
+2 -2
View File
@@ -46,8 +46,8 @@ set TZData(:America/Metlakatla) {
{1489316400 -28800 1 AKDT}
{1509876000 -32400 0 AKST}
{1520766000 -28800 1 AKDT}
{1541325600 -32400 0 AKST}
{1552215600 -28800 1 AKDT}
{1541329200 -28800 0 PST}
{1552215600 -28800 0 AKDT}
{1572775200 -32400 0 AKST}
{1583665200 -28800 1 AKDT}
{1604224800 -32400 0 AKST}
+6 -6
View File
@@ -2,11 +2,11 @@
set TZData(:Asia/Hong_Kong) {
{-9223372036854775808 27402 0 LMT}
{-2056693002 28800 0 HKT}
{-907389000 32400 1 HKST}
{-891667800 28800 0 HKT}
{-884246400 32400 0 JST}
{-766746000 28800 0 HKT}
{-2056690800 28800 0 HKT}
{-900909000 32400 1 HKST}
{-891579600 30600 0 HKT}
{-884248200 32400 0 JST}
{-766659600 28800 0 HKT}
{-747981000 32400 1 HKST}
{-728544600 28800 0 HKT}
{-717049800 32400 1 HKST}
@@ -20,7 +20,7 @@ set TZData(:Asia/Hong_Kong) {
{-591856200 32400 1 HKST}
{-573715800 28800 0 HKT}
{-559801800 32400 1 HKST}
{-542352600 28800 0 HKT}
{-541661400 28800 0 HKT}
{-528352200 32400 1 HKST}
{-510211800 28800 0 HKT}
{-498112200 32400 1 HKST}
+58
View File
@@ -0,0 +1,58 @@
# created by tools/tclZIC.tcl - do not edit
set TZData(:Asia/Qostanay) {
{-9223372036854775808 15268 0 LMT}
{-1441167268 14400 0 +04}
{-1247544000 18000 0 +05}
{354913200 21600 1 +06}
{370720800 21600 0 +06}
{386445600 18000 0 +05}
{386449200 21600 1 +05}
{402256800 18000 0 +05}
{417985200 21600 1 +05}
{433792800 18000 0 +05}
{449607600 21600 1 +05}
{465339600 18000 0 +05}
{481064400 21600 1 +05}
{496789200 18000 0 +05}
{512514000 21600 1 +05}
{528238800 18000 0 +05}
{543963600 21600 1 +05}
{559688400 18000 0 +05}
{575413200 21600 1 +05}
{591138000 18000 0 +05}
{606862800 21600 1 +05}
{622587600 18000 0 +05}
{638312400 21600 1 +05}
{654642000 18000 0 +05}
{670366800 14400 0 +04}
{670370400 18000 1 +04}
{686095200 14400 0 +04}
{695772000 18000 0 +05}
{701816400 21600 1 +05}
{717541200 18000 0 +05}
{733266000 21600 1 +05}
{748990800 18000 0 +05}
{764715600 21600 1 +05}
{780440400 18000 0 +05}
{796165200 21600 1 +05}
{811890000 18000 0 +05}
{828219600 21600 1 +05}
{846363600 18000 0 +05}
{859669200 21600 1 +05}
{877813200 18000 0 +05}
{891118800 21600 1 +05}
{909262800 18000 0 +05}
{922568400 21600 1 +05}
{941317200 18000 0 +05}
{954018000 21600 1 +05}
{972766800 18000 0 +05}
{985467600 21600 1 +05}
{1004216400 18000 0 +05}
{1017522000 21600 1 +05}
{1035666000 18000 0 +05}
{1048971600 21600 1 +05}
{1067115600 18000 0 +05}
{1080421200 21600 1 +05}
{1099170000 21600 0 +06}
}
+1
View File
@@ -54,4 +54,5 @@ set TZData(:Asia/Qyzylorda) {
{1067115600 18000 0 +05}
{1080421200 21600 1 +05}
{1099170000 21600 0 +06}
{1545328800 18000 0 +05}
}
+38 -38
View File
@@ -102,106 +102,106 @@ set TZData(:Asia/Tehran) {
{2105551800 12600 0 +0330}
{2121193800 16200 1 +0330}
{2137087800 12600 0 +0330}
{2152729800 16200 1 +0330}
{2168623800 12600 0 +0330}
{2184265800 16200 1 +0330}
{2200159800 12600 0 +0330}
{2152816200 16200 1 +0330}
{2168710200 12600 0 +0330}
{2184352200 16200 1 +0330}
{2200246200 12600 0 +0330}
{2215888200 16200 1 +0330}
{2231782200 12600 0 +0330}
{2247424200 16200 1 +0330}
{2263318200 12600 0 +0330}
{2278960200 16200 1 +0330}
{2294854200 12600 0 +0330}
{2310496200 16200 1 +0330}
{2326390200 12600 0 +0330}
{2279046600 16200 1 +0330}
{2294940600 12600 0 +0330}
{2310582600 16200 1 +0330}
{2326476600 12600 0 +0330}
{2342118600 16200 1 +0330}
{2358012600 12600 0 +0330}
{2373654600 16200 1 +0330}
{2389548600 12600 0 +0330}
{2405190600 16200 1 +0330}
{2421084600 12600 0 +0330}
{2436726600 16200 1 +0330}
{2452620600 12600 0 +0330}
{2405277000 16200 1 +0330}
{2421171000 12600 0 +0330}
{2436813000 16200 1 +0330}
{2452707000 12600 0 +0330}
{2468349000 16200 1 +0330}
{2484243000 12600 0 +0330}
{2499885000 16200 1 +0330}
{2515779000 12600 0 +0330}
{2531421000 16200 1 +0330}
{2547315000 12600 0 +0330}
{2562957000 16200 1 +0330}
{2578851000 12600 0 +0330}
{2531507400 16200 1 +0330}
{2547401400 12600 0 +0330}
{2563043400 16200 1 +0330}
{2578937400 12600 0 +0330}
{2594579400 16200 1 +0330}
{2610473400 12600 0 +0330}
{2626115400 16200 1 +0330}
{2642009400 12600 0 +0330}
{2657651400 16200 1 +0330}
{2673545400 12600 0 +0330}
{2689187400 16200 1 +0330}
{2705081400 12600 0 +0330}
{2657737800 16200 1 +0330}
{2673631800 12600 0 +0330}
{2689273800 16200 1 +0330}
{2705167800 12600 0 +0330}
{2720809800 16200 1 +0330}
{2736703800 12600 0 +0330}
{2752345800 16200 1 +0330}
{2768239800 12600 0 +0330}
{2783881800 16200 1 +0330}
{2799775800 12600 0 +0330}
{2815417800 16200 1 +0330}
{2831311800 12600 0 +0330}
{2783968200 16200 1 +0330}
{2799862200 12600 0 +0330}
{2815504200 16200 1 +0330}
{2831398200 12600 0 +0330}
{2847040200 16200 1 +0330}
{2862934200 12600 0 +0330}
{2878576200 16200 1 +0330}
{2894470200 12600 0 +0330}
{2910112200 16200 1 +0330}
{2926006200 12600 0 +0330}
{2941648200 16200 1 +0330}
{2957542200 12600 0 +0330}
{2941734600 16200 1 +0330}
{2957628600 12600 0 +0330}
{2973270600 16200 1 +0330}
{2989164600 12600 0 +0330}
{3004806600 16200 1 +0330}
{3020700600 12600 0 +0330}
{3036342600 16200 1 +0330}
{3052236600 12600 0 +0330}
{3067878600 16200 1 +0330}
{3083772600 12600 0 +0330}
{3067965000 16200 1 +0330}
{3083859000 12600 0 +0330}
{3099501000 16200 1 +0330}
{3115395000 12600 0 +0330}
{3131037000 16200 1 +0330}
{3146931000 12600 0 +0330}
{3162573000 16200 1 +0330}
{3178467000 12600 0 +0330}
{3194109000 16200 1 +0330}
{3210003000 12600 0 +0330}
{3194195400 16200 1 +0330}
{3210089400 12600 0 +0330}
{3225731400 16200 1 +0330}
{3241625400 12600 0 +0330}
{3257267400 16200 1 +0330}
{3273161400 12600 0 +0330}
{3288803400 16200 1 +0330}
{3304697400 12600 0 +0330}
{3320339400 16200 1 +0330}
{3336233400 12600 0 +0330}
{3320425800 16200 1 +0330}
{3336319800 12600 0 +0330}
{3351961800 16200 1 +0330}
{3367855800 12600 0 +0330}
{3383497800 16200 1 +0330}
{3399391800 12600 0 +0330}
{3415033800 16200 1 +0330}
{3430927800 12600 0 +0330}
{3446569800 16200 1 +0330}
{3462463800 12600 0 +0330}
{3446656200 16200 1 +0330}
{3462550200 12600 0 +0330}
{3478192200 16200 1 +0330}
{3494086200 12600 0 +0330}
{3509728200 16200 1 +0330}
{3525622200 12600 0 +0330}
{3541264200 16200 1 +0330}
{3557158200 12600 0 +0330}
{3572800200 16200 1 +0330}
{3588694200 12600 0 +0330}
{3572886600 16200 1 +0330}
{3588780600 12600 0 +0330}
{3604422600 16200 1 +0330}
{3620316600 12600 0 +0330}
{3635958600 16200 1 +0330}
{3651852600 12600 0 +0330}
{3667494600 16200 1 +0330}
{3683388600 12600 0 +0330}
{3699030600 16200 1 +0330}
{3714924600 12600 0 +0330}
{3699117000 16200 1 +0330}
{3715011000 12600 0 +0330}
{3730653000 16200 1 +0330}
{3746547000 12600 0 +0330}
{3762189000 16200 1 +0330}
+6 -1
View File
@@ -1,6 +1,11 @@
# created by tools/tclZIC.tcl - do not edit
set TZData(:Pacific/Chuuk) {
{-9223372036854775808 36428 0 LMT}
{-9223372036854775808 -49972 0 LMT}
{-3944628428 36428 0 LMT}
{-2177489228 36000 0 +10}
{-1743674400 32400 0 +09}
{-1606813200 36000 0 +10}
{-907408800 32400 0 +09}
{-770634000 36000 0 +10}
}
+18
View File
@@ -4,5 +4,23 @@ set TZData(:Pacific/Guam) {
{-9223372036854775808 -51660 0 LMT}
{-3944626740 34740 0 LMT}
{-2177487540 36000 0 GST}
{-885549600 32400 0 +09}
{-802256400 36000 0 GST}
{-331891200 39600 1 GDT}
{-281610000 36000 0 GST}
{-73728000 39600 1 GDT}
{-29415540 36000 0 GST}
{-16704000 39600 1 GDT}
{-10659600 36000 0 GST}
{9907200 39600 1 GDT}
{21394800 36000 0 GST}
{41356800 39600 1 GDT}
{52844400 36000 0 GST}
{124819200 39600 1 GDT}
{130863600 36000 0 GST}
{201888000 39600 1 GDT}
{209487660 36000 0 GST}
{230659200 39600 1 GDT}
{241542000 36000 0 GST}
{977493600 36000 0 ChST}
}
+7 -1
View File
@@ -1,8 +1,14 @@
# created by tools/tclZIC.tcl - do not edit
set TZData(:Pacific/Kosrae) {
{-9223372036854775808 39116 0 LMT}
{-9223372036854775808 -47284 0 LMT}
{-3944631116 39116 0 LMT}
{-2177491916 39600 0 +11}
{-1743678000 32400 0 +09}
{-1606813200 39600 0 +11}
{-1041418800 36000 0 +10}
{-907408800 32400 0 +09}
{-770634000 39600 0 +11}
{-7988400 43200 0 +12}
{915105600 39600 0 +11}
}
+4 -1
View File
@@ -3,6 +3,9 @@
set TZData(:Pacific/Kwajalein) {
{-9223372036854775808 40160 0 LMT}
{-2177492960 39600 0 +11}
{-1041418800 36000 0 +10}
{-907408800 32400 0 +09}
{-817462800 39600 0 +11}
{-7988400 -43200 0 -12}
{745848000 43200 0 +12}
{745934400 43200 0 +12}
}
+5
View File
@@ -3,5 +3,10 @@
set TZData(:Pacific/Majuro) {
{-9223372036854775808 41088 0 LMT}
{-2177493888 39600 0 +11}
{-1743678000 32400 0 +09}
{-1606813200 39600 0 +11}
{-1041418800 36000 0 +10}
{-907408800 32400 0 +09}
{-818067600 39600 0 +11}
{-7988400 43200 0 +12}
}
+3 -3
View File
@@ -3,7 +3,7 @@
set TZData(:Pacific/Nauru) {
{-9223372036854775808 40060 0 LMT}
{-1545131260 41400 0 +1130}
{-877347000 32400 0 +09}
{-800960400 41400 0 +1130}
{294323400 43200 0 +12}
{-862918200 32400 0 +09}
{-767350800 41400 0 +1130}
{287418600 43200 0 +12}
}
+2 -1
View File
@@ -1,6 +1,7 @@
# created by tools/tclZIC.tcl - do not edit
set TZData(:Pacific/Palau) {
{-9223372036854775808 32276 0 LMT}
{-9223372036854775808 -54124 0 LMT}
{-3944624276 32276 0 LMT}
{-2177485076 32400 0 +09}
}
+7 -1
View File
@@ -1,6 +1,12 @@
# created by tools/tclZIC.tcl - do not edit
set TZData(:Pacific/Pohnpei) {
{-9223372036854775808 37972 0 LMT}
{-9223372036854775808 -48428 0 LMT}
{-3944629972 37972 0 LMT}
{-2177490772 39600 0 +11}
{-1743678000 32400 0 +09}
{-1606813200 39600 0 +11}
{-1041418800 36000 0 +10}
{-907408800 32400 0 +09}
{-770634000 39600 0 +11}
}
+24 -2
View File
@@ -1,4 +1,26 @@
LibTomMath is hereby released into the Public Domain.
The LibTom license
-- Tom St Denis
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/>
+25
View File
@@ -0,0 +1,25 @@
# libtommath
This is the git repository for [LibTomMath](http://www.libtom.net/LibTomMath/), a free open source portable number theoretic multiple-precision integer (MPI) library written entirely in C.
## Build Status
master: [![Build Status](https://api.travis-ci.org/libtom/libtommath.png?branch=master)](https://travis-ci.org/libtom/libtommath)
develop: [![Build Status](https://api.travis-ci.org/libtom/libtommath.png?branch=develop)](https://travis-ci.org/libtom/libtommath)
API/ABI changes: [check here](https://abi-laboratory.pro/tracker/timeline/libtommath/)
## Summary
The `develop` branch contains the in-development version. Stable releases are tagged.
Documentation is built from the LaTeX file `bn.tex`. There is also limited documentation in `tommath.h`. There is also a document, `tommath.pdf`, which describes the goals of the project and many of the algorithms used.
The project can be build by using `make`. Along with the usual `make`, `make clean` and `make install`, there are several other build targets, see the makefile for details. There are also makefiles for certain specific platforms.
## Testing
Tests are located in `demo/` and can be built in two flavors.
* `make test` creates a test binary that is intended to be run against `mtest`. `mtest` can be built with `make mtest` and test execution is done like `./mtest/mtest | ./test`. `mtest` is creating test vectors using an alternative MPI library and `test` is consuming these vectors to verify correct behavior of ltm
* `make test_standalone` creates a stand-alone test binary that executes several test routines.
+17 -16
View File
@@ -1,4 +1,4 @@
#include <tommath.h>
#include "tommath_private.h"
#ifdef BN_ERROR_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
@@ -9,31 +9,28 @@
* 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, tomstdenis@gmail.com, http://math.libtomcrypt.com
* SPDX-License-Identifier: Unlicense
*/
static const struct {
int code;
char *msg;
int code;
const char *msg;
} msgs[] = {
{ MP_OKAY, "Successful" },
{ MP_MEM, "Out of heap" },
{ MP_VAL, "Value out of range" }
{ MP_OKAY, "Successful" },
{ MP_MEM, "Out of heap" },
{ MP_VAL, "Value out of range" }
};
/* return a char * string for a given code */
char *mp_error_to_string(int code)
const char *mp_error_to_string(int code)
{
int x;
size_t x;
/* scan the lookup table for the given message */
for (x = 0; x < (int)(sizeof(msgs) / sizeof(msgs[0])); x++) {
if (msgs[x].code == code) {
return msgs[x].msg;
}
for (x = 0; x < (sizeof(msgs) / sizeof(msgs[0])); x++) {
if (msgs[x].code == code) {
return msgs[x].msg;
}
}
/* generic reply for invalid code */
@@ -41,3 +38,7 @@ char *mp_error_to_string(int code)
}
#endif
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+128 -112
View File
@@ -1,4 +1,4 @@
#include <tommath.h>
#include "tommath_private.h"
#ifdef BN_FAST_MP_INVMOD_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
@@ -9,136 +9,152 @@
* 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, tomstdenis@gmail.com, http://math.libtomcrypt.com
* SPDX-License-Identifier: Unlicense
*/
/* computes the modular inverse via binary extended euclidean algorithm,
* that is c = 1/a mod b
/* 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
* 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)
int fast_mp_invmod(const mp_int *a, const mp_int *b, mp_int *c)
{
mp_int x, y, u, v, B, D;
int res, neg;
mp_int x, y, u, v, B, D;
int res, neg;
/* 2. [modified] b must be odd */
if (mp_iseven (b) == 1) {
return MP_VAL;
}
/* 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;
}
/* 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;
}
/* 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;
}
/* 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);
/* if one of x,y is zero return an error! */
if ((mp_iszero(&x) == MP_YES) || (mp_iszero(&y) == MP_YES)) {
res = MP_VAL;
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, 1uL);
top:
/* 4. while u is even do */
while (mp_iseven (&u) == 1) {
/* 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) == 1) {
if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) {
goto LBL_ERR;
/* 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;
}
}
/* 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) == 1) {
/* 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) == 1) {
/* D = (D-x)/2 */
if ((res = mp_sub (&D, &x, &D)) != 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;
}
}
}
/* D = D/2 */
if ((res = mp_div_2 (&D, &D)) != MP_OKAY) {
/* 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, 1uL) != MP_EQ) {
res = MP_VAL;
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;
}
/* 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;
}
}
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;
}
/* too big */
while (mp_cmp_mag(&D, b) != MP_LT) {
if ((res = mp_sub(&D, b, &D)) != MP_OKAY) {
goto LBL_ERR;
}
}
if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) {
goto LBL_ERR;
}
}
mp_exch(&D, c);
c->sign = neg;
res = MP_OKAY;
/* if not zero goto step 4 */
if (mp_iszero (&u) == 0) {
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;
LBL_ERR:
mp_clear_multi(&x, &y, &u, &v, &B, &D, NULL);
return res;
}
#endif
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+133 -128
View File
@@ -1,4 +1,4 @@
#include <tommath.h>
#include "tommath_private.h"
#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
@@ -9,10 +9,7 @@
* 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, tomstdenis@gmail.com, http://math.libtomcrypt.com
* SPDX-License-Identifier: Unlicense
*/
/* computes xR**-1 == x (mod N) via Montgomery Reduction
@@ -23,146 +20,154 @@
*
* 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 fast_mp_montgomery_reduce(mp_int *x, const mp_int *n, mp_digit rho)
{
int ix, res, olduse;
mp_word W[MP_WARRAY];
int ix, res, olduse;
mp_word W[MP_WARRAY];
/* get old used count */
olduse = x->used;
if (x->used > (int)MP_WARRAY) {
return MP_VAL;
}
/* grow a as required */
if (x->alloc < n->used + 1) {
if ((res = mp_grow (x, n->used + 1)) != MP_OKAY) {
return res;
}
}
/* get old used count */
olduse = x->used;
/* first we have to get the digits of the input into
* an array of double precision words W[...]
*/
{
register mp_word *_W;
register 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)
*/
register 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
*/
{
register int iy;
register mp_digit *tmpn;
register 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++);
/* grow a as required */
if (x->alloc < (n->used + 1)) {
if ((res = mp_grow(x, n->used + 1)) != MP_OKAY) {
return res;
}
}
}
/* now fix carry for next digit, W[ix+1] */
W[ix + 1] += W[ix] >> ((mp_word) DIGIT_BIT);
}
/* first we have to get the digits of the input into
* an array of double precision words W[...]
*/
{
mp_word *_W;
mp_digit *tmpx;
/* now we have to propagate the carries and
* shift the words downward [all those least
* significant digits we zeroed].
*/
{
register mp_digit *tmpx;
register mp_word *_W, *_W1;
/* alias for the W[] array */
_W = W;
/* nox fix rest of carries */
/* alias for the digits of x*/
tmpx = x->dp;
/* alias for current word */
_W1 = W + ix;
/* copy the digits of a into W[0..a->used-1] */
for (ix = 0; ix < x->used; ix++) {
*_W++ = *tmpx++;
}
/* alias for next word, where the carry goes */
_W = W + ++ix;
/* zero the high words of W[a->used..m->used*2] */
for (; ix < ((n->used * 2) + 1); ix++) {
*_W++ = 0;
}
}
for (; ix <= n->used * 2 + 1; ix++) {
*_W++ += *_W1++ >> ((mp_word) DIGIT_BIT);
}
/* 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 = ((W[ix] & MP_MASK) * rho) & MP_MASK;
/* 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
*/
/* 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 destination word */
tmpx = x->dp;
/* alias for the digits of the modulus */
tmpn = n->dp;
/* alias for shifted double precision result */
_W = W + n->used;
/* Alias for the columns set by an offset of ix */
_W = W + ix;
for (ix = 0; ix < n->used + 1; ix++) {
*tmpx++ = (mp_digit)(*_W++ & ((mp_word) MP_MASK));
}
/* inner loop */
for (iy = 0; iy < n->used; iy++) {
*_W++ += (mp_word)mu * (mp_word)*tmpn++;
}
}
/* 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;
}
}
/* now fix carry for next digit, W[ix+1] */
W[ix + 1] += W[ix] >> (mp_word)DIGIT_BIT;
}
/* set the max used and clamp */
x->used = n->used + 1;
mp_clamp (x);
/* 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;
/* 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;
/* 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++ = *_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
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+49 -48
View File
@@ -1,4 +1,4 @@
#include <tommath.h>
#include "tommath_private.h"
#ifdef BN_FAST_S_MP_MUL_DIGS_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
@@ -9,47 +9,44 @@
* 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, tomstdenis@gmail.com, http://math.libtomcrypt.com
* SPDX-License-Identifier: Unlicense
*/
/* 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
* 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
* 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 fast_s_mp_mul_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs)
{
int olduse, res, pa, ix, iz;
mp_digit W[MP_WARRAY];
register mp_word _W;
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;
}
}
/* 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 = MIN(digs, a->used + b->used);
/* number of output digits to produce */
pa = MIN(digs, a->used + b->used);
/* clear the carry */
_W = 0;
for (ix = 0; ix < pa; ix++) {
/* clear the carry */
_W = 0;
for (ix = 0; ix < pa; ix++) {
int tx, ty;
int iy;
mp_digit *tmpx, *tmpy;
@@ -62,42 +59,46 @@ int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
tmpx = a->dp + tx;
tmpy = b->dp + ty;
/* this is the number of times the loop will iterrate, essentially
/* this is the number of times the loop will iterrate, essentially
while (tx++ < a->used && ty-- >= 0) { ... }
*/
iy = MIN(a->used-tx, ty+1);
/* execute loop */
for (iz = 0; iz < iy; ++iz) {
_W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
_W += (mp_word)*tmpx++ * (mp_word)*tmpy--;
}
/* store term */
W[ix] = ((mp_digit)_W) & MP_MASK;
W[ix] = (mp_digit)_W & MP_MASK;
/* make next carry */
_W = _W >> ((mp_word)DIGIT_BIT);
}
_W = _W >> (mp_word)DIGIT_BIT;
}
/* setup dest */
olduse = c->used;
c->used = pa;
/* setup dest */
olduse = c->used;
c->used = pa;
{
register mp_digit *tmpc;
tmpc = c->dp;
for (ix = 0; ix < pa+1; ix++) {
/* now extract the previous digit [below the carry] */
*tmpc++ = W[ix];
}
{
mp_digit *tmpc;
tmpc = c->dp;
for (ix = 0; 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;
/* clear unused digits [that existed in the old copy of c] */
for (; ix < olduse; ix++) {
*tmpc++ = 0;
}
}
mp_clamp(c);
return MP_OKAY;
}
#endif
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+44 -43
View File
@@ -1,4 +1,4 @@
#include <tommath.h>
#include "tommath_private.h"
#ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
@@ -9,10 +9,7 @@
* 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, tomstdenis@gmail.com, http://math.libtomcrypt.com
* SPDX-License-Identifier: Unlicense
*/
/* this is a modified version of fast_s_mul_digs that only produces
@@ -24,24 +21,24 @@
*
* 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 fast_s_mp_mul_high_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs)
{
int olduse, res, pa, ix, iz;
mp_digit W[MP_WARRAY];
mp_word _W;
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;
}
}
/* 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++) {
/* 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;
@@ -53,42 +50,46 @@ int fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
tmpx = a->dp + tx;
tmpy = b->dp + ty;
/* this is the number of times the loop will iterrate, essentially its
/* this is the number of times the loop will iterrate, essentially its
while (tx++ < a->used && ty-- >= 0) { ... }
*/
iy = MIN(a->used-tx, ty+1);
/* execute loop */
for (iz = 0; iz < iy; iz++) {
_W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
_W += (mp_word)*tmpx++ * (mp_word)*tmpy--;
}
/* store term */
W[ix] = ((mp_digit)_W) & MP_MASK;
W[ix] = (mp_digit)_W & MP_MASK;
/* make next carry */
_W = _W >> ((mp_word)DIGIT_BIT);
}
/* setup dest */
olduse = c->used;
c->used = pa;
_W = _W >> (mp_word)DIGIT_BIT;
}
{
register mp_digit *tmpc;
/* setup dest */
olduse = c->used;
c->used = pa;
tmpc = c->dp + digs;
for (ix = digs; ix < pa; ix++) {
/* now extract the previous digit [below the carry] */
*tmpc++ = W[ix];
}
{
mp_digit *tmpc;
/* clear unused digits [that existed in the old copy of c] */
for (; ix < olduse; ix++) {
*tmpc++ = 0;
}
}
mp_clamp (c);
return MP_OKAY;
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
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+47 -46
View File
@@ -1,4 +1,4 @@
#include <tommath.h>
#include "tommath_private.h"
#ifdef BN_FAST_S_MP_SQR_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
@@ -9,39 +9,36 @@
* 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, tomstdenis@gmail.com, http://math.libtomcrypt.com
* SPDX-License-Identifier: Unlicense
*/
/* 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.
* 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
* (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 fast_s_mp_sqr(const mp_int *a, mp_int *b)
{
int olduse, res, pa, ix, iz;
mp_digit W[MP_WARRAY], *tmpx;
mp_word W1;
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;
}
}
/* 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++) {
/* number of output digits to produce */
W1 = 0;
for (ix = 0; ix < pa; ix++) {
int tx, ty, iy;
mp_word _W;
mp_digit *tmpy;
@@ -62,49 +59,53 @@ int fast_s_mp_sqr (mp_int * a, mp_int * b)
*/
iy = MIN(a->used-tx, ty+1);
/* now for squaring tx can never equal ty
/* 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 = MIN(iy, (ty-tx+1)>>1);
iy = MIN(iy, ((ty-tx)+1)>>1);
/* execute loop */
for (iz = 0; iz < iy; iz++) {
_W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
_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]);
if (((unsigned)ix & 1u) == 0u) {
_W += (mp_word)a->dp[ix>>1] * (mp_word)a->dp[ix>>1];
}
/* store it */
W[ix] = (mp_digit)(_W & MP_MASK);
W[ix] = _W & MP_MASK;
/* make next carry */
W1 = _W >> ((mp_word)DIGIT_BIT);
}
W1 = _W >> (mp_word)DIGIT_BIT;
}
/* setup dest */
olduse = b->used;
b->used = a->used+a->used;
/* 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;
}
{
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;
/* clear unused digits [that existed in the old copy of c] */
for (; ix < olduse; ix++) {
*tmpb++ = 0;
}
}
mp_clamp(b);
return MP_OKAY;
}
#endif
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+20 -20
View File
@@ -1,4 +1,4 @@
#include <tommath.h>
#include "tommath_private.h"
#ifdef BN_MP_2EXPT_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
@@ -9,36 +9,36 @@
* 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, tomstdenis@gmail.com, http://math.libtomcrypt.com
* SPDX-License-Identifier: Unlicense
*/
/* computes a = 2**b
/* 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 mp_2expt(mp_int *a, int b)
{
int res;
int res;
/* zero a as per default */
mp_zero (a);
/* 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;
}
/* 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;
/* 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);
/* put the single bit in its place */
a->dp[b / DIGIT_BIT] = (mp_digit)1 << (mp_digit)(b % DIGIT_BIT);
return MP_OKAY;
return MP_OKAY;
}
#endif
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+18 -18
View File
@@ -1,4 +1,4 @@
#include <tommath.h>
#include "tommath_private.h"
#ifdef BN_MP_ABS_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
@@ -9,31 +9,31 @@
* 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, tomstdenis@gmail.com, http://math.libtomcrypt.com
* SPDX-License-Identifier: Unlicense
*/
/* b = |a|
/* b = |a|
*
* Simple function copies the input and fixes the sign to positive
*/
int
mp_abs (mp_int * a, mp_int * b)
int mp_abs(const mp_int *a, mp_int *b)
{
int res;
int res;
/* copy a to b */
if (a != b) {
if ((res = mp_copy (a, b)) != MP_OKAY) {
return 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;
/* force the sign of b to positive */
b->sign = MP_ZPOS;
return MP_OKAY;
return MP_OKAY;
}
#endif
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+30 -29
View File
@@ -1,4 +1,4 @@
#include <tommath.h>
#include "tommath_private.h"
#ifdef BN_MP_ADD_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
@@ -9,41 +9,42 @@
* 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, tomstdenis@gmail.com, http://math.libtomcrypt.com
* SPDX-License-Identifier: Unlicense
*/
/* high level addition (handles signs) */
int mp_add (mp_int * a, mp_int * b, mp_int * c)
int mp_add(const mp_int *a, const mp_int *b, mp_int *c)
{
int sa, sb, res;
int sa, sb, res;
/* get sign of both inputs */
sa = a->sign;
sb = b->sign;
/* 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 {
/* 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_sub (a, b, c);
}
}
return res;
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
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+74 -77
View File
@@ -1,4 +1,4 @@
#include <tommath.h>
#include "tommath_private.h"
#ifdef BN_MP_ADD_D_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
@@ -9,104 +9,101 @@
* 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, tomstdenis@gmail.com, http://libtom.org
* SPDX-License-Identifier: Unlicense
*/
/* single digit addition */
int
mp_add_d (mp_int * a, mp_digit b, mp_int * c)
int mp_add_d(const mp_int *a, mp_digit b, mp_int *c)
{
int res, ix, oldused;
mp_digit *tmpa, *tmpc, mu;
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;
}
}
/* 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;
/* if a is negative and |a| >= b, call c = |a| - b */
if ((a->sign == MP_NEG) && ((a->used > 1) || (a->dp[0] >= b))) {
mp_int a_ = *a;
/* temporarily fix sign of a */
a_.sign = MP_ZPOS;
/* c = |a| - b */
res = mp_sub_d(a, b, c);
/* c = |a| - b */
res = mp_sub_d(&a_, b, c);
/* fix sign */
a->sign = c->sign = MP_NEG;
/* fix sign */
c->sign = MP_NEG;
/* clamp */
mp_clamp(c);
/* clamp */
mp_clamp(c);
return res;
}
return res;
}
/* old number of used digits in c */
oldused = c->used;
/* old number of used digits in c */
oldused = c->used;
/* sign always positive */
c->sign = MP_ZPOS;
/* source alias */
tmpa = a->dp;
/* source alias */
tmpa = a->dp;
/* destination alias */
tmpc = c->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;
/* 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;
/* 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;
/* 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;
}
/* 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;
}
/* setup count so the clearing of oldused
* can fall through correctly
*/
ix = 1;
}
/* sign always positive */
c->sign = MP_ZPOS;
/* now zero to oldused */
while (ix++ < oldused) {
*tmpc++ = 0;
}
mp_clamp(c);
/* now zero to oldused */
while (ix++ < oldused) {
*tmpc++ = 0;
}
mp_clamp(c);
return MP_OKAY;
return MP_OKAY;
}
#endif
/* $Source$ */
/* $Revision: 0.41 $ */
/* $Date: 2007-04-18 09:58:18 +0000 $ */
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+19 -19
View File
@@ -1,4 +1,4 @@
#include <tommath.h>
#include "tommath_private.h"
#ifdef BN_MP_ADDMOD_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
@@ -9,29 +9,29 @@
* 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, tomstdenis@gmail.com, http://math.libtomcrypt.com
* SPDX-License-Identifier: Unlicense
*/
/* d = a + b (mod c) */
int
mp_addmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
int mp_addmod(const mp_int *a, const mp_int *b, const mp_int *c, mp_int *d)
{
int res;
mp_int t;
int res;
mp_int t;
if ((res = mp_init (&t)) != MP_OKAY) {
return res;
}
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;
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
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+34 -33
View File
@@ -1,4 +1,4 @@
#include <tommath.h>
#include "tommath_private.h"
#ifdef BN_MP_AND_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
@@ -9,45 +9,46 @@
* 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, tomstdenis@gmail.com, http://math.libtomcrypt.com
* SPDX-License-Identifier: Unlicense
*/
/* AND two ints together */
int
mp_and (mp_int * a, mp_int * b, mp_int * c)
int mp_and(const mp_int *a, const mp_int *b, mp_int *c)
{
int res, ix, px;
mp_int t, *x;
int res, ix, px;
mp_int t;
const mp_int *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;
}
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];
}
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;
}
/* 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;
mp_clamp(&t);
mp_exch(c, &t);
mp_clear(&t);
return MP_OKAY;
}
#endif
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+18 -18
View File
@@ -1,4 +1,4 @@
#include <tommath.h>
#include "tommath_private.h"
#ifdef BN_MP_CLAMP_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
@@ -9,32 +9,32 @@
* 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, tomstdenis@gmail.com, http://math.libtomcrypt.com
* SPDX-License-Identifier: Unlicense
*/
/* trim unused digits
/* 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)
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);
}
/* decrease used while the most significant digit is
* zero.
*/
while ((a->used > 0) && (a->dp[a->used - 1] == 0u)) {
--(a->used);
}
/* reset the sign flag if used == 0 */
if (a->used == 0) {
a->sign = MP_ZPOS;
}
/* reset the sign flag if used == 0 */
if (a->used == 0) {
a->sign = MP_ZPOS;
}
}
#endif
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+21 -21
View File
@@ -1,4 +1,4 @@
#include <tommath.h>
#include "tommath_private.h"
#ifdef BN_MP_CLEAR_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
@@ -9,32 +9,32 @@
* 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, tomstdenis@gmail.com, http://math.libtomcrypt.com
* SPDX-License-Identifier: Unlicense
*/
/* clear one (frees) */
void
mp_clear (mp_int * a)
void mp_clear(mp_int *a)
{
int i;
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;
}
/* 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);
/* free ram */
XFREE(a->dp);
/* reset members to make debugging easier */
a->dp = NULL;
a->alloc = a->used = 0;
a->sign = MP_ZPOS;
}
/* reset members to make debugging easier */
a->dp = NULL;
a->alloc = a->used = 0;
a->sign = MP_ZPOS;
}
}
#endif
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+16 -14
View File
@@ -1,4 +1,4 @@
#include <tommath.h>
#include "tommath_private.h"
#ifdef BN_MP_CLEAR_MULTI_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
@@ -9,22 +9,24 @@
* 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, tomstdenis@gmail.com, http://math.libtomcrypt.com
* SPDX-License-Identifier: Unlicense
*/
#include <stdarg.h>
void mp_clear_multi(mp_int *mp, ...)
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);
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
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+23 -23
View File
@@ -1,4 +1,4 @@
#include <tommath.h>
#include "tommath_private.h"
#ifdef BN_MP_CMP_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
@@ -9,31 +9,31 @@
* 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, tomstdenis@gmail.com, http://math.libtomcrypt.com
* SPDX-License-Identifier: Unlicense
*/
/* compare two ints (signed)*/
int
mp_cmp (const mp_int * a, const mp_int * b)
int mp_cmp(const mp_int *a, const 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);
}
/* 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
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+23 -22
View File
@@ -1,4 +1,4 @@
#include <tommath.h>
#include "tommath_private.h"
#ifdef BN_MP_CMP_D_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
@@ -9,32 +9,33 @@
* 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, tomstdenis@gmail.com, http://math.libtomcrypt.com
* SPDX-License-Identifier: Unlicense
*/
/* compare a digit */
int mp_cmp_d(const mp_int * a, mp_digit b)
int mp_cmp_d(const mp_int *a, mp_digit b)
{
/* compare based on sign */
if (a->sign == MP_NEG) {
return MP_LT;
}
/* compare based on sign */
if (a->sign == MP_NEG) {
return MP_LT;
}
/* compare based on magnitude */
if (a->used > 1) {
return MP_GT;
}
/* 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;
}
/* 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
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+32 -31
View File
@@ -1,4 +1,4 @@
#include <tommath.h>
#include "tommath_private.h"
#ifdef BN_MP_CMP_MAG_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
@@ -9,43 +9,44 @@
* 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, tomstdenis@gmail.com, http://math.libtomcrypt.com
* SPDX-License-Identifier: Unlicense
*/
/* compare maginitude of two ints (unsigned) */
int mp_cmp_mag (const mp_int * a, const mp_int * b)
int mp_cmp_mag(const mp_int *a, const mp_int *b)
{
int n;
mp_digit *tmpa, *tmpb;
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) {
/* compare based on # of non-zero digits */
if (a->used > b->used) {
return MP_GT;
}
}
if (*tmpa < *tmpb) {
if (a->used < b->used) {
return MP_LT;
}
}
return MP_EQ;
}
/* 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
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+12 -11
View File
@@ -1,4 +1,4 @@
#include <tommath.h>
#include "tommath_private.h"
#ifdef BN_MP_CNT_LSB_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
@@ -9,13 +9,10 @@
* 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, tomstdenis@gmail.com, http://math.libtomcrypt.com
* SPDX-License-Identifier: Unlicense
*/
static const int lnz[16] = {
static const int lnz[16] = {
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
};
@@ -26,24 +23,28 @@ int mp_cnt_lsb(const mp_int *a)
mp_digit q, qq;
/* easy out */
if (mp_iszero(a) == 1) {
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++);
for (x = 0; (x < a->used) && (a->dp[x] == 0u); x++) {}
q = a->dp[x];
x *= DIGIT_BIT;
/* now scan this digit until a 1 is found */
if ((q & 1) == 0) {
if ((q & 1u) == 0u) {
do {
qq = q & 15;
qq = q & 15u;
x += lnz[qq];
q >>= 4;
} while (qq == 0);
} while (qq == 0u);
}
return x;
}
#endif
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+25
View File
@@ -0,0 +1,25 @@
#include "tommath_private.h"
#ifdef BN_MP_COMPLEMENT_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.
*
* SPDX-License-Identifier: Unlicense
*/
/* b = ~a */
int mp_complement(const mp_int *a, mp_int *b)
{
int res = mp_neg(a, b);
return (res == MP_OKAY) ? mp_sub_d(b, 1uL, b) : res;
}
#endif
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+39 -39
View File
@@ -1,4 +1,4 @@
#include <tommath.h>
#include "tommath_private.h"
#ifdef BN_MP_COPY_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
@@ -9,56 +9,56 @@
* 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, tomstdenis@gmail.com, http://math.libtomcrypt.com
* SPDX-License-Identifier: Unlicense
*/
/* copy, b = a */
int
mp_copy (const mp_int * a, mp_int * b)
int mp_copy(const mp_int *a, mp_int *b)
{
int res, n;
int res, n;
/* if dst == src do nothing */
if (a == b) {
return MP_OKAY;
}
/* 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;
}
}
/* 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 */
{
register mp_digit *tmpa, *tmpb;
/* zero b and copy the parameters over */
{
mp_digit *tmpa, *tmpb;
/* pointer aliases */
/* pointer aliases */
/* source */
tmpa = a->dp;
/* source */
tmpa = a->dp;
/* destination */
tmpb = b->dp;
/* destination */
tmpb = b->dp;
/* copy all the digits */
for (n = 0; n < a->used; n++) {
*tmpb++ = *tmpa++;
}
/* copy all the digits */
for (n = 0; n < a->used; n++) {
*tmpb++ = *tmpa++;
}
/* clear high digits */
for (; n < b->used; n++) {
*tmpb++ = 0;
}
}
/* 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;
/* copy used count and sign */
b->used = a->used;
b->sign = a->sign;
return MP_OKAY;
}
#endif
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+23 -23
View File
@@ -1,4 +1,4 @@
#include <tommath.h>
#include "tommath_private.h"
#ifdef BN_MP_COUNT_BITS_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
@@ -9,33 +9,33 @@
* 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, tomstdenis@gmail.com, http://math.libtomcrypt.com
* SPDX-License-Identifier: Unlicense
*/
/* returns the number of bits in an int */
int
mp_count_bits (const mp_int * a)
int mp_count_bits(const mp_int *a)
{
int r;
mp_digit q;
int r;
mp_digit q;
/* shortcut */
if (a->used == 0) {
return 0;
}
/* 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;
/* 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
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+231 -222
View File
@@ -1,4 +1,4 @@
#include <tommath.h>
#include "tommath_private.h"
#ifdef BN_MP_DIV_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
@@ -9,77 +9,74 @@
* 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, tomstdenis@gmail.com, http://math.libtomcrypt.com
* SPDX-License-Identifier: Unlicense
*/
#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)
int mp_div(const mp_int *a, const 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) == 1) {
return MP_VAL;
}
/* 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;
}
/* 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)) {
mp_set(&tq, 1uL);
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;
}
}
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;
}
/* 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;
@@ -87,202 +84,214 @@ LBL_ERR:
#else
/* integer signed division.
/* 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
* 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
* 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)
int mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d)
{
mp_int q, x, y, t1, t2;
int res, n, t, i, norm, neg;
mp_int q, x, y, t1, t2;
int res, n, t, i, norm, neg;
/* is divisor zero ? */
if (mp_iszero (b) == 1) {
return MP_VAL;
}
/* 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 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_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(&t1)) != MP_OKAY) {
goto LBL_Q;
}
if ((res = mp_init (&t2)) != MP_OKAY) {
goto LBL_T1;
}
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(&x, a)) != MP_OKAY) {
goto LBL_T2;
}
if ((res = mp_init_copy (&y, b)) != MP_OKAY) {
goto LBL_X;
}
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;
/* 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;
}
/* normalize both x and y, ensure that y >= b/2, [b == 2**DIGIT_BIT] */
norm = mp_count_bits(&y) % DIGIT_BIT;
if (norm < (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;
/* 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) {
/* 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;
}
}
}
/* reset y by shifting it back down */
mp_rshd (&y, n - t);
while (mp_cmp(&x, &y) != MP_LT) {
++(q.dp[n - t]);
if ((res = mp_sub(&x, &y, &x)) != MP_OKAY) {
goto LBL_Y;
}
}
/* step 3. for i from n down to (t + 1) */
for (i = n; i >= (t + 1); i--) {
if (i > x.used) {
continue;
}
/* reset y by shifting it back down */
mp_rshd(&y, n - t);
/* 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));
}
/* step 3. for i from n down to (t + 1) */
for (i = n; i >= (t + 1); i--) {
if (i > x.used) {
continue;
}
/* while (q{i-t-1} * (yt * b + y{t-1})) >
xi * b**2 + xi-1 * b + xi-2
do q{i-t-1} -= 1;
/* 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 << (mp_digit)DIGIT_BIT) - (mp_digit)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] + 1uL) & (mp_digit)MP_MASK;
do {
q.dp[(i - t) - 1] = (q.dp[(i - t) - 1] - 1uL) & (mp_digit)MP_MASK;
/* find left hand */
mp_zero(&t1);
t1.dp[0] = ((t - 1) < 0) ? 0u : 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) ? 0u : x.dp[i - 2];
t2.dp[1] = ((i - 1) < 0) ? 0u : 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 quotient and x is the remainder
* [which we have to normalize]
*/
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;
/* get sign before writing to c */
x.sign = (x.used == 0) ? MP_ZPOS : a->sign;
if (c != NULL) {
mp_clamp(&q);
mp_exch(&q, c);
c->sign = neg;
}
if (d != NULL) {
if ((res = mp_div_2d(&x, norm, &x, NULL)) != MP_OKAY) {
goto LBL_Y;
}
mp_exch(&x, d);
}
/* 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);
res = MP_OKAY;
/* 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 quotient and x is the remainder
* [which we have to normalize]
*/
/* get sign before writing to c */
x.sign = x.used == 0 ? MP_ZPOS : a->sign;
if (c != NULL) {
mp_clamp (&q);
mp_exch (&q, c);
c->sign = neg;
}
if (d != NULL) {
mp_div_2d (&x, norm, &x, NULL);
mp_exch (&x, d);
}
res = MP_OKAY;
LBL_Y:mp_clear (&y);
LBL_X:mp_clear (&x);
LBL_T2:mp_clear (&t2);
LBL_T1:mp_clear (&t1);
LBL_Q:mp_clear (&q);
return res;
LBL_Y:
mp_clear(&y);
LBL_X:
mp_clear(&x);
LBL_T2:
mp_clear(&t2);
LBL_T1:
mp_clear(&t1);
LBL_Q:
mp_clear(&q);
return res;
}
#endif
#endif
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+41 -40
View File
@@ -1,4 +1,4 @@
#include <tommath.h>
#include "tommath_private.h"
#ifdef BN_MP_DIV_2_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
@@ -9,56 +9,57 @@
* 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, tomstdenis@gmail.com, http://math.libtomcrypt.com
* SPDX-License-Identifier: Unlicense
*/
/* b = a/2 */
int mp_div_2(mp_int * a, mp_int * b)
int mp_div_2(const mp_int *a, mp_int *b)
{
int x, res, oldused;
int x, res, oldused;
/* copy */
if (b->alloc < a->used) {
if ((res = mp_grow (b, a->used)) != MP_OKAY) {
return res;
}
}
/* copy */
if (b->alloc < a->used) {
if ((res = mp_grow(b, a->used)) != MP_OKAY) {
return res;
}
}
oldused = b->used;
b->used = a->used;
{
register mp_digit r, rr, *tmpa, *tmpb;
oldused = b->used;
b->used = a->used;
{
mp_digit r, rr, *tmpa, *tmpb;
/* source alias */
tmpa = a->dp + b->used - 1;
/* source alias */
tmpa = a->dp + b->used - 1;
/* dest alias */
tmpb = b->dp + b->used - 1;
/* dest alias */
tmpb = b->dp + b->used - 1;
/* carry */
r = 0;
for (x = b->used - 1; x >= 0; x--) {
/* get the carry for the next iteration */
rr = *tmpa & 1;
/* carry */
r = 0;
for (x = b->used - 1; x >= 0; x--) {
/* get the carry for the next iteration */
rr = *tmpa & 1u;
/* shift the current digit, add in carry and store */
*tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1));
/* shift the current digit, add in carry and store */
*tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1));
/* forward carry to next iteration */
r = rr;
}
/* forward carry to next iteration */
r = rr;
}
/* zero excess digits */
tmpb = b->dp + b->used;
for (x = b->used; x < oldused; x++) {
*tmpb++ = 0;
}
}
b->sign = a->sign;
mp_clamp (b);
return MP_OKAY;
/* zero excess digits */
tmpb = b->dp + b->used;
for (x = b->used; x < oldused; x++) {
*tmpb++ = 0;
}
}
b->sign = a->sign;
mp_clamp(b);
return MP_OKAY;
}
#endif
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+56 -66
View File
@@ -1,4 +1,4 @@
#include <tommath.h>
#include "tommath_private.h"
#ifdef BN_MP_DIV_2D_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
@@ -9,85 +9,75 @@
* 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, tomstdenis@gmail.com, http://math.libtomcrypt.com
* SPDX-License-Identifier: Unlicense
*/
/* shift right by a certain bit count (store quotient in c, optional remainder in d) */
int mp_div_2d (const mp_int * a, int b, mp_int * c, mp_int * d)
int mp_div_2d(const mp_int *a, int b, mp_int *c, mp_int *d)
{
mp_digit D, r, rr;
int x, res;
mp_int t;
mp_digit D, r, rr;
int x, res;
/* if the shift count is <= 0 then we do no work */
if (b <= 0) {
res = mp_copy (a, c);
if (d != NULL) {
mp_zero (d);
}
return res;
}
if ((res = mp_init (&t)) != MP_OKAY) {
return res;
}
/* get the remainder */
if (d != NULL) {
if ((res = mp_mod_2d (a, b, &t)) != MP_OKAY) {
mp_clear (&t);
/* if the shift count is <= 0 then we do no work */
if (b <= 0) {
res = mp_copy(a, c);
if (d != NULL) {
mp_zero(d);
}
return res;
}
}
}
/* copy */
if ((res = mp_copy (a, c)) != MP_OKAY) {
mp_clear (&t);
return res;
}
/* copy */
if ((res = mp_copy(a, c)) != MP_OKAY) {
return res;
}
/* 'a' should not be used after here - it might be the same as d */
/* shift by as many digits in the bit count */
if (b >= (int)DIGIT_BIT) {
mp_rshd (c, b / DIGIT_BIT);
}
/* get the remainder */
if (d != NULL) {
if ((res = mp_mod_2d(a, b, d)) != MP_OKAY) {
return res;
}
}
/* shift any bit count < DIGIT_BIT */
D = (mp_digit) (b % DIGIT_BIT);
if (D != 0) {
register mp_digit *tmpc, mask, shift;
/* shift by as many digits in the bit count */
if (b >= DIGIT_BIT) {
mp_rshd(c, b / DIGIT_BIT);
}
/* mask */
mask = (((mp_digit)1) << D) - 1;
/* shift any bit count < DIGIT_BIT */
D = (mp_digit)(b % DIGIT_BIT);
if (D != 0u) {
mp_digit *tmpc, mask, shift;
/* shift for lsb */
shift = DIGIT_BIT - D;
/* mask */
mask = ((mp_digit)1 << D) - 1uL;
/* alias */
tmpc = c->dp + (c->used - 1);
/* shift for lsb */
shift = (mp_digit)DIGIT_BIT - D;
/* carry */
r = 0;
for (x = c->used - 1; x >= 0; x--) {
/* get the lower bits of this word in a temp */
rr = *tmpc & mask;
/* alias */
tmpc = c->dp + (c->used - 1);
/* shift the current word and mix in the carry bits from the previous word */
*tmpc = (*tmpc >> D) | (r << shift);
--tmpc;
/* carry */
r = 0;
for (x = c->used - 1; x >= 0; x--) {
/* get the lower bits of this word in a temp */
rr = *tmpc & mask;
/* set the carry to the carry bits of the current word found above */
r = rr;
}
}
mp_clamp (c);
if (d != NULL) {
mp_exch (&t, d);
}
mp_clear (&t);
return MP_OKAY;
/* shift the current word and mix in the carry bits from the previous word */
*tmpc = (*tmpc >> D) | (r << shift);
--tmpc;
/* set the carry to the carry bits of the current word found above */
r = rr;
}
}
mp_clamp(c);
return MP_OKAY;
}
#endif
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+49 -49
View File
@@ -1,4 +1,4 @@
#include <tommath.h>
#include "tommath_private.h"
#ifdef BN_MP_DIV_3_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
@@ -9,67 +9,67 @@
* 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, tomstdenis@gmail.com, http://math.libtomcrypt.com
* SPDX-License-Identifier: Unlicense
*/
/* divide by three (based on routine from MPI and the GMP manual) */
int
mp_div_3 (mp_int * a, mp_int *c, mp_digit * d)
int mp_div_3(const mp_int *a, mp_int *c, mp_digit *d)
{
mp_int q;
mp_word w, t;
mp_digit b;
int res, ix;
/* b = 2**DIGIT_BIT / 3 */
b = (((mp_word)1) << ((mp_word)DIGIT_BIT)) / ((mp_word)3);
mp_int q;
mp_word w, t;
mp_digit b;
int res, ix;
if ((res = mp_init_size(&q, a->used)) != MP_OKAY) {
return res;
}
q.used = a->used;
q.sign = a->sign;
w = 0;
for (ix = a->used - 1; ix >= 0; ix--) {
w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]);
/* b = 2**DIGIT_BIT / 3 */
b = ((mp_word)1 << (mp_word)DIGIT_BIT) / (mp_word)3;
if (w >= 3) {
/* multiply w by [1/3] */
t = (w * ((mp_word)b)) >> ((mp_word)DIGIT_BIT);
if ((res = mp_init_size(&q, a->used)) != MP_OKAY) {
return res;
}
/* now subtract 3 * [w/3] from w, to get the remainder */
w -= t+t+t;
q.used = a->used;
q.sign = a->sign;
w = 0;
for (ix = a->used - 1; ix >= 0; ix--) {
w = (w << (mp_word)DIGIT_BIT) | (mp_word)a->dp[ix];
/* fixup the remainder as required since
* the optimization is not exact.
*/
while (w >= 3) {
t += 1;
w -= 3;
}
if (w >= 3u) {
/* multiply w by [1/3] */
t = (w * (mp_word)b) >> (mp_word)DIGIT_BIT;
/* now subtract 3 * [w/3] from w, to get the remainder */
w -= t+t+t;
/* fixup the remainder as required since
* the optimization is not exact.
*/
while (w >= 3u) {
t += 1u;
w -= 3u;
}
} else {
t = 0;
t = 0;
}
q.dp[ix] = (mp_digit)t;
}
}
/* [optional] store the remainder */
if (d != NULL) {
*d = (mp_digit)w;
}
/* [optional] store the remainder */
if (d != NULL) {
*d = (mp_digit)w;
}
/* [optional] store the quotient */
if (c != NULL) {
mp_clamp(&q);
mp_exch(&q, c);
}
mp_clear(&q);
return res;
/* [optional] store the quotient */
if (c != NULL) {
mp_clamp(&q);
mp_exch(&q, c);
}
mp_clear(&q);
return res;
}
#endif
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+73 -84
View File
@@ -1,4 +1,4 @@
#include <tommath.h>
#include "tommath_private.h"
#ifdef BN_MP_DIV_D_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
@@ -9,102 +9,91 @@
* 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, tomstdenis@gmail.com, http://math.libtomcrypt.com
* SPDX-License-Identifier: Unlicense
*/
static int s_is_power_of_two(mp_digit b, int *p)
{
int x;
/* quick out - if (b & (b-1)) isn't zero, b isn't a power of two */
if ((b==0) || (b & (b-1))) {
return 0;
}
for (x = 1; x < DIGIT_BIT; x++) {
if (b == (((mp_digit)1)<<x)) {
*p = x;
return 1;
}
}
return 0;
}
/* single digit division (based on routine from MPI) */
int mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d)
int mp_div_d(const mp_int *a, mp_digit b, mp_int *c, mp_digit *d)
{
mp_int q;
mp_word w;
mp_digit t;
int res, ix;
mp_int q;
mp_word w;
mp_digit t;
int res, ix;
/* cannot divide by zero */
if (b == 0) {
return MP_VAL;
}
/* cannot divide by zero */
if (b == 0u) {
return MP_VAL;
}
/* quick outs */
if (b == 1 || mp_iszero(a) == 1) {
if (d != NULL) {
*d = 0;
}
if (c != NULL) {
return mp_copy(a, c);
}
return MP_OKAY;
}
/* quick outs */
if ((b == 1u) || (mp_iszero(a) == MP_YES)) {
if (d != NULL) {
*d = 0;
}
if (c != NULL) {
return mp_copy(a, c);
}
return MP_OKAY;
}
/* power of two ? */
if (s_is_power_of_two(b, &ix) == 1) {
if (d != NULL) {
*d = a->dp[0] & ((((mp_digit)1)<<ix) - 1);
}
if (c != NULL) {
return mp_div_2d(a, ix, c, NULL);
}
return MP_OKAY;
}
/* power of two ? */
if (((b & (b-1)) == 0)) {
for (ix = 1; ix < DIGIT_BIT; ix++) {
if (b == (((mp_digit)1)<<ix)) {
break;
}
}
if (d != NULL) {
*d = a->dp[0] & (((mp_digit)1<<(mp_digit)ix) - 1uL);
}
if (c != NULL) {
return mp_div_2d(a, ix, c, NULL);
}
return MP_OKAY;
}
#ifdef BN_MP_DIV_3_C
/* three? */
if (b == 3) {
return mp_div_3(a, c, d);
}
/* three? */
if (b == 3u) {
return mp_div_3(a, c, d);
}
#endif
/* no easy answer [c'est la vie]. Just division */
if ((res = mp_init_size(&q, a->used)) != MP_OKAY) {
return res;
}
q.used = a->used;
q.sign = a->sign;
w = 0;
for (ix = a->used - 1; ix >= 0; ix--) {
w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]);
if (w >= b) {
t = (mp_digit)(w / b);
w -= ((mp_word)t) * ((mp_word)b);
/* no easy answer [c'est la vie]. Just division */
if ((res = mp_init_size(&q, a->used)) != MP_OKAY) {
return res;
}
q.used = a->used;
q.sign = a->sign;
w = 0;
for (ix = a->used - 1; ix >= 0; ix--) {
w = (w << (mp_word)DIGIT_BIT) | (mp_word)a->dp[ix];
if (w >= b) {
t = (mp_digit)(w / b);
w -= (mp_word)t * (mp_word)b;
} else {
t = 0;
t = 0;
}
q.dp[ix] = (mp_digit)t;
}
if (d != NULL) {
*d = (mp_digit)w;
}
if (c != NULL) {
mp_clamp(&q);
mp_exch(&q, c);
}
mp_clear(&q);
return res;
q.dp[ix] = t;
}
if (d != NULL) {
*d = (mp_digit)w;
}
if (c != NULL) {
mp_clamp(&q);
mp_exch(&q, c);
}
mp_clear(&q);
return res;
}
#endif
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+10 -9
View File
@@ -1,4 +1,4 @@
#include <tommath.h>
#include "tommath_private.h"
#ifdef BN_MP_DR_IS_MODULUS_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
@@ -9,14 +9,11 @@
* 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, tomstdenis@gmail.com, http://math.libtomcrypt.com
* SPDX-License-Identifier: Unlicense
*/
/* determines if a number is a valid DR modulus */
int mp_dr_is_modulus(mp_int *a)
int mp_dr_is_modulus(const mp_int *a)
{
int ix;
@@ -29,11 +26,15 @@ int mp_dr_is_modulus(mp_int *a)
* but the first digit must be equal to -1 (mod b).
*/
for (ix = 1; ix < a->used; ix++) {
if (a->dp[ix] != MP_MASK) {
return 0;
}
if (a->dp[ix] != MP_MASK) {
return 0;
}
}
return 1;
}
#endif
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+49 -47
View File
@@ -1,4 +1,4 @@
#include <tommath.h>
#include "tommath_private.h"
#ifdef BN_MP_DR_REDUCE_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
@@ -9,10 +9,7 @@
* 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, tomstdenis@gmail.com, http://math.libtomcrypt.com
* SPDX-License-Identifier: Unlicense
*/
/* reduce "x" in place modulo "n" using the Diminished Radix algorithm.
@@ -29,62 +26,67 @@
*
* Input x must be in the range 0 <= x <= (n-1)**2
*/
int
mp_dr_reduce (mp_int * x, mp_int * n, mp_digit k)
int mp_dr_reduce(mp_int *x, const mp_int *n, mp_digit k)
{
int err, i, m;
mp_word r;
mp_digit mu, *tmpx1, *tmpx2;
int err, i, m;
mp_word r;
mp_digit mu, *tmpx1, *tmpx2;
/* m = digits in modulus */
m = n->used;
/* m = digits in modulus */
m = n->used;
/* ensure that "x" has at least 2m digits */
if (x->alloc < m + m) {
if ((err = mp_grow (x, m + m)) != MP_OKAY) {
return err;
}
}
/* ensure that "x" has at least 2m digits */
if (x->alloc < (m + m)) {
if ((err = mp_grow(x, m + m)) != MP_OKAY) {
return err;
}
}
/* top of loop, this is where the code resumes if
* another reduction pass is required.
*/
/* top of loop, this is where the code resumes if
* another reduction pass is required.
*/
top:
/* aliases for digits */
/* alias for lower half of x */
tmpx1 = x->dp;
/* aliases for digits */
/* alias for lower half of x */
tmpx1 = x->dp;
/* alias for upper half of x, or x/B**m */
tmpx2 = x->dp + m;
/* alias for upper half of x, or x/B**m */
tmpx2 = x->dp + m;
/* set carry to zero */
mu = 0;
/* set carry to zero */
mu = 0;
/* compute (x mod B**m) + k * [x/B**m] inline and inplace */
for (i = 0; i < m; i++) {
r = ((mp_word)*tmpx2++) * ((mp_word)k) + *tmpx1 + mu;
/* compute (x mod B**m) + k * [x/B**m] inline and inplace */
for (i = 0; i < m; i++) {
r = ((mp_word)*tmpx2++ * (mp_word)k) + *tmpx1 + mu;
*tmpx1++ = (mp_digit)(r & MP_MASK);
mu = (mp_digit)(r >> ((mp_word)DIGIT_BIT));
}
}
/* set final carry */
*tmpx1++ = mu;
/* set final carry */
*tmpx1++ = mu;
/* zero words above m */
for (i = m + 1; i < x->used; i++) {
/* zero words above m */
for (i = m + 1; i < x->used; i++) {
*tmpx1++ = 0;
}
}
/* clamp, sub and return */
mp_clamp (x);
/* clamp, sub and return */
mp_clamp(x);
/* if x >= n then subtract and reduce again
* Each successive "recursion" makes the input smaller and smaller.
*/
if (mp_cmp_mag (x, n) != MP_LT) {
s_mp_sub(x, n, x);
goto top;
}
return MP_OKAY;
/* if x >= n then subtract and reduce again
* Each successive "recursion" makes the input smaller and smaller.
*/
if (mp_cmp_mag(x, n) != MP_LT) {
if ((err = s_mp_sub(x, n, x)) != MP_OKAY) {
return err;
}
goto top;
}
return MP_OKAY;
}
#endif
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+8 -8
View File
@@ -1,4 +1,4 @@
#include <tommath.h>
#include "tommath_private.h"
#ifdef BN_MP_DR_SETUP_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
@@ -9,20 +9,20 @@
* 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, tomstdenis@gmail.com, http://math.libtomcrypt.com
* SPDX-License-Identifier: Unlicense
*/
/* determines the setup value */
void mp_dr_setup(mp_int *a, mp_digit *d)
void mp_dr_setup(const mp_int *a, mp_digit *d)
{
/* the casts are required if DIGIT_BIT is one less than
* the number of bits in a mp_digit [e.g. DIGIT_BIT==31]
*/
*d = (mp_digit)((((mp_word)1) << ((mp_word)DIGIT_BIT)) -
((mp_word)a->dp[0]));
*d = (mp_digit)(((mp_word)1 << (mp_word)DIGIT_BIT) - (mp_word)a->dp[0]);
}
#endif
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+12 -12
View File
@@ -1,4 +1,4 @@
#include <tommath.h>
#include "tommath_private.h"
#ifdef BN_MP_EXCH_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
@@ -9,22 +9,22 @@
* 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, tomstdenis@gmail.com, http://math.libtomcrypt.com
* SPDX-License-Identifier: Unlicense
*/
/* swap the elements of two integers, for cases where you can't simply swap the
/* swap the elements of two integers, for cases where you can't simply swap the
* mp_int pointers around
*/
void
mp_exch (mp_int * a, mp_int * b)
void mp_exch(mp_int *a, mp_int *b)
{
mp_int t;
mp_int t;
t = *a;
*a = *b;
*b = t;
t = *a;
*a = *b;
*b = t;
}
#endif
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+84
View File
@@ -0,0 +1,84 @@
#include "tommath_private.h"
#ifdef BN_MP_EXPORT_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.
*
* SPDX-License-Identifier: Unlicense
*/
/* based on gmp's mpz_export.
* see http://gmplib.org/manual/Integer-Import-and-Export.html
*/
int mp_export(void *rop, size_t *countp, int order, size_t size,
int endian, size_t nails, const mp_int *op)
{
int result;
size_t odd_nails, nail_bytes, i, j, bits, count;
unsigned char odd_nail_mask;
mp_int t;
if ((result = mp_init_copy(&t, op)) != MP_OKAY) {
return result;
}
if (endian == 0) {
union {
unsigned int i;
char c[4];
} lint;
lint.i = 0x01020304;
endian = (lint.c[0] == '\x04') ? -1 : 1;
}
odd_nails = (nails % 8u);
odd_nail_mask = 0xff;
for (i = 0; i < odd_nails; ++i) {
odd_nail_mask ^= (unsigned char)(1u << (7u - i));
}
nail_bytes = nails / 8u;
bits = (size_t)mp_count_bits(&t);
count = (bits / ((size * 8u) - nails)) + (((bits % ((size * 8u) - nails)) != 0u) ? 1u : 0u);
for (i = 0; i < count; ++i) {
for (j = 0; j < size; ++j) {
unsigned char *byte = (unsigned char *)rop +
(((order == -1) ? i : ((count - 1u) - i)) * size) +
((endian == -1) ? j : ((size - 1u) - j));
if (j >= (size - nail_bytes)) {
*byte = 0;
continue;
}
*byte = (unsigned char)((j == ((size - nail_bytes) - 1u)) ? (t.dp[0] & odd_nail_mask) : (t.dp[0] & 0xFFuL));
if ((result = mp_div_2d(&t, (j == ((size - nail_bytes) - 1u)) ? (int)(8u - odd_nails) : 8, &t, NULL)) != MP_OKAY) {
mp_clear(&t);
return result;
}
}
}
mp_clear(&t);
if (countp != NULL) {
*countp = count;
}
return MP_OKAY;
}
#endif
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+10 -38
View File
@@ -1,4 +1,4 @@
#include <tommath.h>
#include "tommath_private.h"
#ifdef BN_MP_EXPT_D_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
@@ -9,45 +9,17 @@
* 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, tomstdenis@gmail.com, http://math.libtomcrypt.com
* SPDX-License-Identifier: Unlicense
*/
/* calculate c = a**b using a square-multiply algorithm */
int mp_expt_d (mp_int * a, mp_digit b, mp_int * c)
/* wrapper function for mp_expt_d_ex() */
int mp_expt_d(const mp_int *a, mp_digit b, mp_int *c)
{
int res, x;
mp_int g;
if ((res = mp_init_copy (&g, a)) != MP_OKAY) {
return res;
}
/* set initial result */
mp_set (c, 1);
for (x = 0; x < (int) DIGIT_BIT; x++) {
/* square */
if ((res = mp_sqr (c, c)) != MP_OKAY) {
mp_clear (&g);
return res;
}
/* if the bit is set multiply */
if ((b & (mp_digit) (((mp_digit)1) << (DIGIT_BIT - 1))) != 0) {
if ((res = mp_mul (c, &g, c)) != MP_OKAY) {
mp_clear (&g);
return res;
}
}
/* shift to next bit */
b <<= 1;
}
mp_clear (&g);
return MP_OKAY;
return mp_expt_d_ex(a, b, c, 0);
}
#endif
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+79
View File
@@ -0,0 +1,79 @@
#include "tommath_private.h"
#ifdef BN_MP_EXPT_D_EX_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.
*
* SPDX-License-Identifier: Unlicense
*/
/* calculate c = a**b using a square-multiply algorithm */
int mp_expt_d_ex(const mp_int *a, mp_digit b, mp_int *c, int fast)
{
int res;
unsigned int x;
mp_int g;
if ((res = mp_init_copy(&g, a)) != MP_OKAY) {
return res;
}
/* set initial result */
mp_set(c, 1uL);
if (fast != 0) {
while (b > 0u) {
/* if the bit is set multiply */
if ((b & 1u) != 0u) {
if ((res = mp_mul(c, &g, c)) != MP_OKAY) {
mp_clear(&g);
return res;
}
}
/* square */
if (b > 1u) {
if ((res = mp_sqr(&g, &g)) != MP_OKAY) {
mp_clear(&g);
return res;
}
}
/* shift to next bit */
b >>= 1;
}
} else {
for (x = 0; x < (unsigned)DIGIT_BIT; x++) {
/* square */
if ((res = mp_sqr(c, c)) != MP_OKAY) {
mp_clear(&g);
return res;
}
/* if the bit is set multiply */
if ((b & ((mp_digit)1 << (DIGIT_BIT - 1))) != 0u) {
if ((res = mp_mul(c, &g, c)) != MP_OKAY) {
mp_clear(&g);
return res;
}
}
/* shift to next bit */
b <<= 1;
}
} /* if ... else */
mp_clear(&g);
return MP_OKAY;
}
#endif
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+63 -62
View File
@@ -1,4 +1,4 @@
#include <tommath.h>
#include "tommath_private.h"
#ifdef BN_MP_EXPTMOD_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
@@ -9,10 +9,7 @@
* 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, tomstdenis@gmail.com, http://math.libtomcrypt.com
* SPDX-License-Identifier: Unlicense
*/
@@ -21,88 +18,92 @@
* embedded in the normal function but that wasted alot of stack space
* for nothing (since 99% of the time the Montgomery code would be called)
*/
int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
int mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y)
{
int dr;
int dr;
/* modulus P must be positive */
if (P->sign == MP_NEG) {
return MP_VAL;
}
/* modulus P must be positive */
if (P->sign == MP_NEG) {
return MP_VAL;
}
/* if exponent X is negative we have to recurse */
if (X->sign == MP_NEG) {
/* if exponent X is negative we have to recurse */
if (X->sign == MP_NEG) {
#ifdef BN_MP_INVMOD_C
mp_int tmpG, tmpX;
int err;
mp_int tmpG, tmpX;
int err;
/* first compute 1/G mod P */
if ((err = mp_init(&tmpG)) != MP_OKAY) {
return err;
}
if ((err = mp_invmod(G, P, &tmpG)) != MP_OKAY) {
mp_clear(&tmpG);
return err;
}
/* first compute 1/G mod P */
if ((err = mp_init(&tmpG)) != MP_OKAY) {
return err;
}
if ((err = mp_invmod(G, P, &tmpG)) != MP_OKAY) {
mp_clear(&tmpG);
return err;
}
/* now get |X| */
if ((err = mp_init(&tmpX)) != MP_OKAY) {
mp_clear(&tmpG);
return err;
}
if ((err = mp_abs(X, &tmpX)) != MP_OKAY) {
mp_clear_multi(&tmpG, &tmpX, NULL);
return err;
}
/* now get |X| */
if ((err = mp_init(&tmpX)) != MP_OKAY) {
mp_clear(&tmpG);
return err;
}
if ((err = mp_abs(X, &tmpX)) != MP_OKAY) {
mp_clear_multi(&tmpG, &tmpX, NULL);
return err;
}
/* and now compute (1/G)**|X| instead of G**X [X < 0] */
err = mp_exptmod(&tmpG, &tmpX, P, Y);
mp_clear_multi(&tmpG, &tmpX, NULL);
return err;
#else
/* no invmod */
return MP_VAL;
/* and now compute (1/G)**|X| instead of G**X [X < 0] */
err = mp_exptmod(&tmpG, &tmpX, P, Y);
mp_clear_multi(&tmpG, &tmpX, NULL);
return err;
#else
/* no invmod */
return MP_VAL;
#endif
}
}
/* modified diminished radix reduction */
/* modified diminished radix reduction */
#if defined(BN_MP_REDUCE_IS_2K_L_C) && defined(BN_MP_REDUCE_2K_L_C) && defined(BN_S_MP_EXPTMOD_C)
if (mp_reduce_is_2k_l(P) == MP_YES) {
return s_mp_exptmod(G, X, P, Y, 1);
}
if (mp_reduce_is_2k_l(P) == MP_YES) {
return s_mp_exptmod(G, X, P, Y, 1);
}
#endif
#ifdef BN_MP_DR_IS_MODULUS_C
/* is it a DR modulus? */
dr = mp_dr_is_modulus(P);
/* is it a DR modulus? */
dr = mp_dr_is_modulus(P);
#else
/* default to no */
dr = 0;
/* default to no */
dr = 0;
#endif
#ifdef BN_MP_REDUCE_IS_2K_C
/* if not, is it a unrestricted DR modulus? */
if (dr == 0) {
dr = mp_reduce_is_2k(P) << 1;
}
/* if not, is it a unrestricted DR modulus? */
if (dr == 0) {
dr = mp_reduce_is_2k(P) << 1;
}
#endif
/* if the modulus is odd or dr != 0 use the montgomery method */
/* if the modulus is odd or dr != 0 use the montgomery method */
#ifdef BN_MP_EXPTMOD_FAST_C
if (mp_isodd (P) == 1 || dr != 0) {
return mp_exptmod_fast (G, X, P, Y, dr);
} else {
if ((mp_isodd(P) == MP_YES) || (dr != 0)) {
return mp_exptmod_fast(G, X, P, Y, dr);
} else {
#endif
#ifdef BN_S_MP_EXPTMOD_C
/* otherwise use the generic Barrett reduction technique */
return s_mp_exptmod (G, X, P, Y, 0);
/* otherwise use the generic Barrett reduction technique */
return s_mp_exptmod(G, X, P, Y, 0);
#else
/* no exptmod for evens */
return MP_VAL;
/* no exptmod for evens */
return MP_VAL;
#endif
#ifdef BN_MP_EXPTMOD_FAST_C
}
}
#endif
}
#endif
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+246 -243
View File
@@ -1,4 +1,4 @@
#include <tommath.h>
#include "tommath_private.h"
#ifdef BN_MP_EXPTMOD_FAST_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
@@ -9,10 +9,7 @@
* 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, tomstdenis@gmail.com, http://math.libtomcrypt.com
* SPDX-License-Identifier: Unlicense
*/
/* computes Y == G**X mod P, HAC pp.616, Algorithm 14.85
@@ -24,293 +21,299 @@
*/
#ifdef MP_LOW_MEM
#define TAB_SIZE 32
# define TAB_SIZE 32
#else
#define TAB_SIZE 256
# define TAB_SIZE 256
#endif
int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode)
int mp_exptmod_fast(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y, int redmode)
{
mp_int M[TAB_SIZE], res;
mp_digit buf, mp;
int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize;
mp_int M[TAB_SIZE], res;
mp_digit buf, mp;
int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize;
/* use a pointer to the reduction algorithm. This allows us to use
* one of many reduction algorithms without modding the guts of
* the code with if statements everywhere.
*/
int (*redux)(mp_int*,mp_int*,mp_digit);
/* use a pointer to the reduction algorithm. This allows us to use
* one of many reduction algorithms without modding the guts of
* the code with if statements everywhere.
*/
int (*redux)(mp_int *x, const mp_int *n, mp_digit rho);
/* find window size */
x = mp_count_bits (X);
if (x <= 7) {
winsize = 2;
} else if (x <= 36) {
winsize = 3;
} else if (x <= 140) {
winsize = 4;
} else if (x <= 450) {
winsize = 5;
} else if (x <= 1303) {
winsize = 6;
} else if (x <= 3529) {
winsize = 7;
} else {
winsize = 8;
}
/* find window size */
x = mp_count_bits(X);
if (x <= 7) {
winsize = 2;
} else if (x <= 36) {
winsize = 3;
} else if (x <= 140) {
winsize = 4;
} else if (x <= 450) {
winsize = 5;
} else if (x <= 1303) {
winsize = 6;
} else if (x <= 3529) {
winsize = 7;
} else {
winsize = 8;
}
#ifdef MP_LOW_MEM
if (winsize > 5) {
winsize = 5;
}
if (winsize > 5) {
winsize = 5;
}
#endif
/* init M array */
/* init first cell */
if ((err = mp_init(&M[1])) != MP_OKAY) {
return err;
}
/* now init the second half of the array */
for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
if ((err = mp_init(&M[x])) != MP_OKAY) {
for (y = 1<<(winsize-1); y < x; y++) {
mp_clear (&M[y]);
}
mp_clear(&M[1]);
/* init M array */
/* init first cell */
if ((err = mp_init_size(&M[1], P->alloc)) != MP_OKAY) {
return err;
}
}
}
/* determine and setup reduction code */
if (redmode == 0) {
#ifdef BN_MP_MONTGOMERY_SETUP_C
/* now setup montgomery */
if ((err = mp_montgomery_setup (P, &mp)) != MP_OKAY) {
goto LBL_M;
}
/* now init the second half of the array */
for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
if ((err = mp_init_size(&M[x], P->alloc)) != MP_OKAY) {
for (y = 1<<(winsize-1); y < x; y++) {
mp_clear(&M[y]);
}
mp_clear(&M[1]);
return err;
}
}
/* determine and setup reduction code */
if (redmode == 0) {
#ifdef BN_MP_MONTGOMERY_SETUP_C
/* now setup montgomery */
if ((err = mp_montgomery_setup(P, &mp)) != MP_OKAY) {
goto LBL_M;
}
#else
err = MP_VAL;
goto LBL_M;
err = MP_VAL;
goto LBL_M;
#endif
/* automatically pick the comba one if available (saves quite a few calls/ifs) */
/* automatically pick the comba one if available (saves quite a few calls/ifs) */
#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C
if (((P->used * 2 + 1) < MP_WARRAY) &&
P->used < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
redux = fast_mp_montgomery_reduce;
} else
if ((((P->used * 2) + 1) < (int)MP_WARRAY) &&
(P->used < (1 << ((CHAR_BIT * sizeof(mp_word)) - (2 * DIGIT_BIT))))) {
redux = fast_mp_montgomery_reduce;
} else
#endif
{
{
#ifdef BN_MP_MONTGOMERY_REDUCE_C
/* use slower baseline Montgomery method */
redux = mp_montgomery_reduce;
/* use slower baseline Montgomery method */
redux = mp_montgomery_reduce;
#else
err = MP_VAL;
goto LBL_M;
err = MP_VAL;
goto LBL_M;
#endif
}
} else if (redmode == 1) {
}
} else if (redmode == 1) {
#if defined(BN_MP_DR_SETUP_C) && defined(BN_MP_DR_REDUCE_C)
/* setup DR reduction for moduli of the form B**k - b */
mp_dr_setup(P, &mp);
redux = mp_dr_reduce;
/* setup DR reduction for moduli of the form B**k - b */
mp_dr_setup(P, &mp);
redux = mp_dr_reduce;
#else
err = MP_VAL;
goto LBL_M;
err = MP_VAL;
goto LBL_M;
#endif
} else {
} else {
#if defined(BN_MP_REDUCE_2K_SETUP_C) && defined(BN_MP_REDUCE_2K_C)
/* setup DR reduction for moduli of the form 2**k - b */
if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY) {
goto LBL_M;
}
redux = mp_reduce_2k;
/* setup DR reduction for moduli of the form 2**k - b */
if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY) {
goto LBL_M;
}
redux = mp_reduce_2k;
#else
err = MP_VAL;
goto LBL_M;
err = MP_VAL;
goto LBL_M;
#endif
}
}
/* setup result */
if ((err = mp_init (&res)) != MP_OKAY) {
goto LBL_M;
}
/* setup result */
if ((err = mp_init_size(&res, P->alloc)) != MP_OKAY) {
goto LBL_M;
}
/* create M table
*
/* create M table
*
*
* The first half of the table is not computed though accept for M[0] and M[1]
*/
*
* The first half of the table is not computed though accept for M[0] and M[1]
*/
if (redmode == 0) {
if (redmode == 0) {
#ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
/* now we need R mod m */
if ((err = mp_montgomery_calc_normalization (&res, P)) != MP_OKAY) {
goto LBL_RES;
}
#else
err = MP_VAL;
goto LBL_RES;
/* now we need R mod m */
if ((err = mp_montgomery_calc_normalization(&res, P)) != MP_OKAY) {
goto LBL_RES;
}
/* now set M[1] to G * R mod m */
if ((err = mp_mulmod(G, &res, P, &M[1])) != MP_OKAY) {
goto LBL_RES;
}
#else
err = MP_VAL;
goto LBL_RES;
#endif
} else {
mp_set(&res, 1uL);
if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) {
goto LBL_RES;
}
}
/* now set M[1] to G * R mod m */
if ((err = mp_mulmod (G, &res, P, &M[1])) != MP_OKAY) {
goto LBL_RES;
}
} else {
mp_set(&res, 1);
if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) {
goto LBL_RES;
}
}
/* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times */
if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) {
goto LBL_RES;
}
for (x = 0; x < (winsize - 1); x++) {
if ((err = mp_sqr (&M[1 << (winsize - 1)], &M[1 << (winsize - 1)])) != MP_OKAY) {
/* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times */
if ((err = mp_copy(&M[1], &M[(size_t)1 << (winsize - 1)])) != MP_OKAY) {
goto LBL_RES;
}
if ((err = redux (&M[1 << (winsize - 1)], P, mp)) != MP_OKAY) {
goto LBL_RES;
}
}
}
/* create upper table */
for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {
if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) {
goto LBL_RES;
}
if ((err = redux (&M[x], P, mp)) != MP_OKAY) {
goto LBL_RES;
}
}
/* set initial mode and bit cnt */
mode = 0;
bitcnt = 1;
buf = 0;
digidx = X->used - 1;
bitcpy = 0;
bitbuf = 0;
for (;;) {
/* grab next digit as required */
if (--bitcnt == 0) {
/* if digidx == -1 we are out of digits so break */
if (digidx == -1) {
break;
for (x = 0; x < (winsize - 1); x++) {
if ((err = mp_sqr(&M[(size_t)1 << (winsize - 1)], &M[(size_t)1 << (winsize - 1)])) != MP_OKAY) {
goto LBL_RES;
}
/* read next digit and reset bitcnt */
buf = X->dp[digidx--];
bitcnt = (int)DIGIT_BIT;
}
/* grab the next msb from the exponent */
y = (mp_digit)(buf >> (DIGIT_BIT - 1)) & 1;
buf <<= (mp_digit)1;
/* if the bit is zero and mode == 0 then we ignore it
* These represent the leading zero bits before the first 1 bit
* in the exponent. Technically this opt is not required but it
* does lower the # of trivial squaring/reductions used
*/
if (mode == 0 && y == 0) {
continue;
}
/* if the bit is zero and mode == 1 then we square */
if (mode == 1 && y == 0) {
if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
goto LBL_RES;
if ((err = redux(&M[(size_t)1 << (winsize - 1)], P, mp)) != MP_OKAY) {
goto LBL_RES;
}
if ((err = redux (&res, P, mp)) != MP_OKAY) {
goto LBL_RES;
}
/* create upper table */
for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {
if ((err = mp_mul(&M[x - 1], &M[1], &M[x])) != MP_OKAY) {
goto LBL_RES;
}
continue;
}
if ((err = redux(&M[x], P, mp)) != MP_OKAY) {
goto LBL_RES;
}
}
/* else we add it to the window */
bitbuf |= (y << (winsize - ++bitcpy));
mode = 2;
/* set initial mode and bit cnt */
mode = 0;
bitcnt = 1;
buf = 0;
digidx = X->used - 1;
bitcpy = 0;
bitbuf = 0;
if (bitcpy == winsize) {
/* ok window is filled so square as required and multiply */
/* square first */
for (x = 0; x < winsize; x++) {
if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
goto LBL_RES;
}
if ((err = redux (&res, P, mp)) != MP_OKAY) {
goto LBL_RES;
}
for (;;) {
/* grab next digit as required */
if (--bitcnt == 0) {
/* if digidx == -1 we are out of digits so break */
if (digidx == -1) {
break;
}
/* read next digit and reset bitcnt */
buf = X->dp[digidx--];
bitcnt = (int)DIGIT_BIT;
}
/* then multiply */
if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) {
goto LBL_RES;
}
if ((err = redux (&res, P, mp)) != MP_OKAY) {
goto LBL_RES;
/* grab the next msb from the exponent */
y = (mp_digit)(buf >> (DIGIT_BIT - 1)) & 1;
buf <<= (mp_digit)1;
/* if the bit is zero and mode == 0 then we ignore it
* These represent the leading zero bits before the first 1 bit
* in the exponent. Technically this opt is not required but it
* does lower the # of trivial squaring/reductions used
*/
if ((mode == 0) && (y == 0)) {
continue;
}
/* empty window and reset */
bitcpy = 0;
bitbuf = 0;
mode = 1;
}
}
/* if bits remain then square/multiply */
if (mode == 2 && bitcpy > 0) {
/* square then multiply if the bit is set */
for (x = 0; x < bitcpy; x++) {
if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
goto LBL_RES;
}
if ((err = redux (&res, P, mp)) != MP_OKAY) {
goto LBL_RES;
/* if the bit is zero and mode == 1 then we square */
if ((mode == 1) && (y == 0)) {
if ((err = mp_sqr(&res, &res)) != MP_OKAY) {
goto LBL_RES;
}
if ((err = redux(&res, P, mp)) != MP_OKAY) {
goto LBL_RES;
}
continue;
}
/* get next bit of the window */
bitbuf <<= 1;
if ((bitbuf & (1 << winsize)) != 0) {
/* then multiply */
if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) {
goto LBL_RES;
}
if ((err = redux (&res, P, mp)) != MP_OKAY) {
goto LBL_RES;
}
/* else we add it to the window */
bitbuf |= (y << (winsize - ++bitcpy));
mode = 2;
if (bitcpy == winsize) {
/* ok window is filled so square as required and multiply */
/* square first */
for (x = 0; x < winsize; x++) {
if ((err = mp_sqr(&res, &res)) != MP_OKAY) {
goto LBL_RES;
}
if ((err = redux(&res, P, mp)) != MP_OKAY) {
goto LBL_RES;
}
}
/* then multiply */
if ((err = mp_mul(&res, &M[bitbuf], &res)) != MP_OKAY) {
goto LBL_RES;
}
if ((err = redux(&res, P, mp)) != MP_OKAY) {
goto LBL_RES;
}
/* empty window and reset */
bitcpy = 0;
bitbuf = 0;
mode = 1;
}
}
}
}
if (redmode == 0) {
/* fixup result if Montgomery reduction is used
* recall that any value in a Montgomery system is
* actually multiplied by R mod n. So we have
* to reduce one more time to cancel out the factor
* of R.
*/
if ((err = redux(&res, P, mp)) != MP_OKAY) {
goto LBL_RES;
}
}
/* if bits remain then square/multiply */
if ((mode == 2) && (bitcpy > 0)) {
/* square then multiply if the bit is set */
for (x = 0; x < bitcpy; x++) {
if ((err = mp_sqr(&res, &res)) != MP_OKAY) {
goto LBL_RES;
}
if ((err = redux(&res, P, mp)) != MP_OKAY) {
goto LBL_RES;
}
/* swap res with Y */
mp_exch (&res, Y);
err = MP_OKAY;
LBL_RES:mp_clear (&res);
/* get next bit of the window */
bitbuf <<= 1;
if ((bitbuf & (1 << winsize)) != 0) {
/* then multiply */
if ((err = mp_mul(&res, &M[1], &res)) != MP_OKAY) {
goto LBL_RES;
}
if ((err = redux(&res, P, mp)) != MP_OKAY) {
goto LBL_RES;
}
}
}
}
if (redmode == 0) {
/* fixup result if Montgomery reduction is used
* recall that any value in a Montgomery system is
* actually multiplied by R mod n. So we have
* to reduce one more time to cancel out the factor
* of R.
*/
if ((err = redux(&res, P, mp)) != MP_OKAY) {
goto LBL_RES;
}
}
/* swap res with Y */
mp_exch(&res, Y);
err = MP_OKAY;
LBL_RES:
mp_clear(&res);
LBL_M:
mp_clear(&M[1]);
for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
mp_clear (&M[x]);
}
return err;
mp_clear(&M[1]);
for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
mp_clear(&M[x]);
}
return err;
}
#endif
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+80 -36
View File
@@ -1,4 +1,4 @@
#include <tommath.h>
#include "tommath_private.h"
#ifdef BN_MP_EXTEUCLID_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
@@ -9,18 +9,15 @@
* 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, tomstdenis@gmail.com, http://math.libtomcrypt.com
* SPDX-License-Identifier: Unlicense
*/
/* Extended euclidean algorithm of (a, b) produces
/* Extended euclidean algorithm of (a, b) produces
a*u1 + b*u2 = u3
*/
int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3)
int mp_exteuclid(const mp_int *a, const mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3)
{
mp_int u1,u2,u3,v1,v2,v3,t1,t2,t3,q,tmp;
mp_int u1, u2, u3, v1, v2, v3, t1, t2, t3, q, tmp;
int err;
if ((err = mp_init_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL)) != MP_OKAY) {
@@ -28,51 +25,98 @@ int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3)
}
/* initialize, (u1,u2,u3) = (1,0,a) */
mp_set(&u1, 1);
if ((err = mp_copy(a, &u3)) != MP_OKAY) { goto _ERR; }
mp_set(&u1, 1uL);
if ((err = mp_copy(a, &u3)) != MP_OKAY) {
goto LBL_ERR;
}
/* initialize, (v1,v2,v3) = (0,1,b) */
mp_set(&v2, 1);
if ((err = mp_copy(b, &v3)) != MP_OKAY) { goto _ERR; }
mp_set(&v2, 1uL);
if ((err = mp_copy(b, &v3)) != MP_OKAY) {
goto LBL_ERR;
}
/* loop while v3 != 0 */
while (mp_iszero(&v3) == MP_NO) {
/* q = u3/v3 */
if ((err = mp_div(&u3, &v3, &q, NULL)) != MP_OKAY) { goto _ERR; }
/* q = u3/v3 */
if ((err = mp_div(&u3, &v3, &q, NULL)) != MP_OKAY) {
goto LBL_ERR;
}
/* (t1,t2,t3) = (u1,u2,u3) - (v1,v2,v3)q */
if ((err = mp_mul(&v1, &q, &tmp)) != MP_OKAY) { goto _ERR; }
if ((err = mp_sub(&u1, &tmp, &t1)) != MP_OKAY) { goto _ERR; }
if ((err = mp_mul(&v2, &q, &tmp)) != MP_OKAY) { goto _ERR; }
if ((err = mp_sub(&u2, &tmp, &t2)) != MP_OKAY) { goto _ERR; }
if ((err = mp_mul(&v3, &q, &tmp)) != MP_OKAY) { goto _ERR; }
if ((err = mp_sub(&u3, &tmp, &t3)) != MP_OKAY) { goto _ERR; }
/* (t1,t2,t3) = (u1,u2,u3) - (v1,v2,v3)q */
if ((err = mp_mul(&v1, &q, &tmp)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sub(&u1, &tmp, &t1)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_mul(&v2, &q, &tmp)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sub(&u2, &tmp, &t2)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_mul(&v3, &q, &tmp)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sub(&u3, &tmp, &t3)) != MP_OKAY) {
goto LBL_ERR;
}
/* (u1,u2,u3) = (v1,v2,v3) */
if ((err = mp_copy(&v1, &u1)) != MP_OKAY) { goto _ERR; }
if ((err = mp_copy(&v2, &u2)) != MP_OKAY) { goto _ERR; }
if ((err = mp_copy(&v3, &u3)) != MP_OKAY) { goto _ERR; }
/* (u1,u2,u3) = (v1,v2,v3) */
if ((err = mp_copy(&v1, &u1)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_copy(&v2, &u2)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_copy(&v3, &u3)) != MP_OKAY) {
goto LBL_ERR;
}
/* (v1,v2,v3) = (t1,t2,t3) */
if ((err = mp_copy(&t1, &v1)) != MP_OKAY) { goto _ERR; }
if ((err = mp_copy(&t2, &v2)) != MP_OKAY) { goto _ERR; }
if ((err = mp_copy(&t3, &v3)) != MP_OKAY) { goto _ERR; }
/* (v1,v2,v3) = (t1,t2,t3) */
if ((err = mp_copy(&t1, &v1)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_copy(&t2, &v2)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_copy(&t3, &v3)) != MP_OKAY) {
goto LBL_ERR;
}
}
/* make sure U3 >= 0 */
if (u3.sign == MP_NEG) {
mp_neg(&u1, &u1);
mp_neg(&u2, &u2);
mp_neg(&u3, &u3);
if ((err = mp_neg(&u1, &u1)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_neg(&u2, &u2)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_neg(&u3, &u3)) != MP_OKAY) {
goto LBL_ERR;
}
}
/* copy result out */
if (U1 != NULL) { mp_exch(U1, &u1); }
if (U2 != NULL) { mp_exch(U2, &u2); }
if (U3 != NULL) { mp_exch(U3, &u3); }
if (U1 != NULL) {
mp_exch(U1, &u1);
}
if (U2 != NULL) {
mp_exch(U2, &u2);
}
if (U3 != NULL) {
mp_exch(U3, &u3);
}
err = MP_OKAY;
_ERR: mp_clear_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL);
LBL_ERR:
mp_clear_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL);
return err;
}
#endif
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+27 -22
View File
@@ -1,4 +1,4 @@
#include <tommath.h>
#include "tommath_private.h"
#ifdef BN_MP_FREAD_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
@@ -9,55 +9,60 @@
* 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, tomstdenis@gmail.com, http://math.libtomcrypt.com
* SPDX-License-Identifier: Unlicense
*/
#ifndef LTM_NO_FILE
/* read a bigint from a file stream in ASCII */
int mp_fread(mp_int *a, int radix, FILE *stream)
{
int err, ch, neg, y;
unsigned pos;
/* clear a */
mp_zero(a);
/* if first digit is - then set negative */
ch = fgetc(stream);
if (ch == '-') {
if (ch == (int)'-') {
neg = MP_NEG;
ch = fgetc(stream);
} else {
neg = MP_ZPOS;
}
for (;;) {
/* find y in the radix map */
for (y = 0; y < radix; y++) {
if (mp_s_rmap[y] == ch) {
break;
}
}
if (y == radix) {
pos = (unsigned)(ch - (int)'(');
if (mp_s_rmap_reverse_sz < pos) {
break;
}
y = (int)mp_s_rmap_reverse[pos];
if ((y == 0xff) || (y >= radix)) {
break;
}
/* shift up and add */
if ((err = mp_mul_d(a, radix, a)) != MP_OKAY) {
if ((err = mp_mul_d(a, (mp_digit)radix, a)) != MP_OKAY) {
return err;
}
if ((err = mp_add_d(a, y, a)) != MP_OKAY) {
if ((err = mp_add_d(a, (mp_digit)y, a)) != MP_OKAY) {
return err;
}
ch = fgetc(stream);
}
if (mp_cmp_d(a, 0) != MP_EQ) {
if (mp_cmp_d(a, 0uL) != MP_EQ) {
a->sign = neg;
}
return MP_OKAY;
}
#endif
#endif
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+20 -17
View File
@@ -1,4 +1,4 @@
#include <tommath.h>
#include "tommath_private.h"
#ifdef BN_MP_FWRITE_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
@@ -9,40 +9,43 @@
* 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, tomstdenis@gmail.com, http://math.libtomcrypt.com
* SPDX-License-Identifier: Unlicense
*/
int mp_fwrite(mp_int *a, int radix, FILE *stream)
#ifndef LTM_NO_FILE
int mp_fwrite(const mp_int *a, int radix, FILE *stream)
{
char *buf;
int err, len, x;
if ((err = mp_radix_size(a, radix, &len)) != MP_OKAY) {
return err;
}
buf = OPT_CAST(char) XMALLOC (len);
buf = OPT_CAST(char) XMALLOC((size_t)len);
if (buf == NULL) {
return MP_MEM;
}
if ((err = mp_toradix(a, buf, radix)) != MP_OKAY) {
XFREE (buf);
XFREE(buf);
return err;
}
for (x = 0; x < len; x++) {
if (fputc(buf[x], stream) == EOF) {
XFREE (buf);
return MP_VAL;
}
if (fputc((int)buf[x], stream) == EOF) {
XFREE(buf);
return MP_VAL;
}
}
XFREE (buf);
XFREE(buf);
return MP_OKAY;
}
#endif
#endif
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+77 -74
View File
@@ -1,4 +1,4 @@
#include <tommath.h>
#include "tommath_private.h"
#ifdef BN_MP_GCD_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
@@ -9,93 +9,96 @@
* 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, tomstdenis@gmail.com, http://math.libtomcrypt.com
* SPDX-License-Identifier: Unlicense
*/
/* Greatest Common Divisor using the binary method */
int mp_gcd (mp_int * a, mp_int * b, mp_int * c)
int mp_gcd(const mp_int *a, const mp_int *b, mp_int *c)
{
mp_int u, v;
int k, u_lsb, v_lsb, res;
mp_int u, v;
int k, u_lsb, v_lsb, res;
/* either zero than gcd is the largest */
if (mp_iszero (a) == MP_YES) {
return mp_abs (b, c);
}
if (mp_iszero (b) == MP_YES) {
return mp_abs (a, c);
}
/* either zero than gcd is the largest */
if (mp_iszero(a) == MP_YES) {
return mp_abs(b, c);
}
if (mp_iszero(b) == MP_YES) {
return mp_abs(a, c);
}
/* get copies of a and b we can modify */
if ((res = mp_init_copy (&u, a)) != MP_OKAY) {
return res;
}
/* get copies of a and b we can modify */
if ((res = mp_init_copy(&u, a)) != MP_OKAY) {
return res;
}
if ((res = mp_init_copy (&v, b)) != MP_OKAY) {
goto LBL_U;
}
if ((res = mp_init_copy(&v, b)) != MP_OKAY) {
goto LBL_U;
}
/* must be positive for the remainder of the algorithm */
u.sign = v.sign = MP_ZPOS;
/* must be positive for the remainder of the algorithm */
u.sign = v.sign = MP_ZPOS;
/* B1. Find the common power of two for u and v */
u_lsb = mp_cnt_lsb(&u);
v_lsb = mp_cnt_lsb(&v);
k = MIN(u_lsb, v_lsb);
/* B1. Find the common power of two for u and v */
u_lsb = mp_cnt_lsb(&u);
v_lsb = mp_cnt_lsb(&v);
k = MIN(u_lsb, v_lsb);
if (k > 0) {
/* divide the power of two out */
if ((res = mp_div_2d(&u, k, &u, NULL)) != MP_OKAY) {
goto LBL_V;
}
if (k > 0) {
/* divide the power of two out */
if ((res = mp_div_2d(&u, k, &u, NULL)) != MP_OKAY) {
goto LBL_V;
}
if ((res = mp_div_2d(&v, k, &v, NULL)) != MP_OKAY) {
goto LBL_V;
}
}
if ((res = mp_div_2d(&v, k, &v, NULL)) != MP_OKAY) {
goto LBL_V;
}
}
/* divide any remaining factors of two out */
if (u_lsb != k) {
if ((res = mp_div_2d(&u, u_lsb - k, &u, NULL)) != MP_OKAY) {
goto LBL_V;
}
}
/* divide any remaining factors of two out */
if (u_lsb != k) {
if ((res = mp_div_2d(&u, u_lsb - k, &u, NULL)) != MP_OKAY) {
goto LBL_V;
}
}
if (v_lsb != k) {
if ((res = mp_div_2d(&v, v_lsb - k, &v, NULL)) != MP_OKAY) {
goto LBL_V;
}
}
if (v_lsb != k) {
if ((res = mp_div_2d(&v, v_lsb - k, &v, NULL)) != MP_OKAY) {
goto LBL_V;
}
}
while (mp_iszero(&v) == 0) {
/* make sure v is the largest */
if (mp_cmp_mag(&u, &v) == MP_GT) {
/* swap u and v to make sure v is >= u */
mp_exch(&u, &v);
}
/* subtract smallest from largest */
if ((res = s_mp_sub(&v, &u, &v)) != MP_OKAY) {
goto LBL_V;
}
/* Divide out all factors of two */
if ((res = mp_div_2d(&v, mp_cnt_lsb(&v), &v, NULL)) != MP_OKAY) {
goto LBL_V;
}
}
while (mp_iszero(&v) == MP_NO) {
/* make sure v is the largest */
if (mp_cmp_mag(&u, &v) == MP_GT) {
/* swap u and v to make sure v is >= u */
mp_exch(&u, &v);
}
/* multiply by 2**k which we divided out at the beginning */
if ((res = mp_mul_2d (&u, k, c)) != MP_OKAY) {
goto LBL_V;
}
c->sign = MP_ZPOS;
res = MP_OKAY;
LBL_V:mp_clear (&u);
LBL_U:mp_clear (&v);
return res;
/* subtract smallest from largest */
if ((res = s_mp_sub(&v, &u, &v)) != MP_OKAY) {
goto LBL_V;
}
/* Divide out all factors of two */
if ((res = mp_div_2d(&v, mp_cnt_lsb(&v), &v, NULL)) != MP_OKAY) {
goto LBL_V;
}
}
/* multiply by 2**k which we divided out at the beginning */
if ((res = mp_mul_2d(&u, k, c)) != MP_OKAY) {
goto LBL_V;
}
c->sign = MP_ZPOS;
res = MP_OKAY;
LBL_V:
mp_clear(&u);
LBL_U:
mp_clear(&v);
return res;
}
#endif
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */

Some files were not shown because too many files have changed in this diff Show More