mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2025-02-05 10:39:54 +00:00
remove PyCrypto, copy AES/SHA256/Util.number into the allmydata/ tree
This commit is contained in:
parent
3f7588e43d
commit
b7703df6a5
@ -60,7 +60,6 @@
|
||||
^\.figleaf\.el$
|
||||
^instdir($|/)
|
||||
^src/zfec/build($|/)
|
||||
^src/Crypto/build($|/)
|
||||
^_test_memory($|/)
|
||||
|
||||
# _version.py is generated at build time, and never checked in
|
||||
@ -79,3 +78,7 @@
|
||||
# that is currently installed (or it is missing).
|
||||
^src/simplejson/setuptools-.*\.egg$
|
||||
^src/zfec/setuptools-.*\.egg$
|
||||
|
||||
# generated crypto extension modules
|
||||
^src/allmydata/Crypto/[^/]*/.*\.so$
|
||||
|
||||
|
13
Makefile
13
Makefile
@ -61,7 +61,7 @@ PP=PYTHONPATH=$(PYTHONPATH)
|
||||
make-version:
|
||||
$(PYTHON) misc/make-version.py "allmydata-tahoe" "src/allmydata/_version.py"
|
||||
|
||||
build: make-version build-zfec build-Crypto build-foolscap build-simplejson
|
||||
build: make-version build-zfec build-foolscap build-simplejson
|
||||
$(PP) $(PYTHON) ./setup.py $(EXTRA_SETUP_ARGS) install --prefix="$(INSTDIR)" --install-lib="$(INSTDIR)/lib" --install-scripts="$(INSTDIR)/bin"
|
||||
|
||||
build-zfec:
|
||||
@ -76,10 +76,6 @@ build-simplejson:
|
||||
cd src/simplejson && \
|
||||
$(PP) $(PYTHON) ./setup.py $(EXTRA_SETUP_ARGS) install --single-version-externally-managed --prefix="$(INSTDIR)" --record="$(INSTDIR)/simplejson_install.log" --install-lib="$(INSTDIR)/lib" --install-scripts="$(INSTDIR)/bin"
|
||||
|
||||
build-Crypto:
|
||||
cd src/Crypto && \
|
||||
$(PP) $(PYTHON) ./setup.py $(EXTRA_SETUP_ARGS) install --prefix="$(INSTDIR)" --record="$(INSTDIR)/Crypto_install.log" --install-lib="$(INSTDIR)/lib" --install-scripts="$(INSTDIR)/bin"
|
||||
|
||||
clean-zfec:
|
||||
-cd src/zfec && \
|
||||
$(PP) $(PYTHON) ./setup.py clean --all
|
||||
@ -88,9 +84,6 @@ clean-foolscap:
|
||||
-cd src/foolscap && \
|
||||
$(PP) $(PYTHON) ./setup.py clean --all
|
||||
|
||||
clean-Crypto:
|
||||
cd src/Crypto && \
|
||||
$(PP) $(PYTHON) ./setup.py clean --all
|
||||
|
||||
|
||||
# RUNNING
|
||||
@ -209,15 +202,15 @@ test-clean:
|
||||
find . |grep -v allfiles.tmp |sort >allfiles.tmp.new
|
||||
diff allfiles.tmp.old allfiles.tmp.new
|
||||
|
||||
clean: clean-zfec clean-Crypto clean-foolscap
|
||||
clean: clean-zfec clean-foolscap
|
||||
rm -rf build
|
||||
rm -f debian
|
||||
rm -rf instdir
|
||||
find src/allmydata -name '*.so' -print0 |xargs -0 rm
|
||||
|
||||
install:
|
||||
cd src/zfec && python ./setup.py install && cd ../..
|
||||
cd src/foolscap && python ./setup.py install && cd ../..
|
||||
cd src/Crypto && python ./setup.py install && cd ../..
|
||||
cd src/simplejson && python ./setup.py install && cd ../..
|
||||
python ./setup.py install
|
||||
|
||||
|
13
README
13
README
@ -120,9 +120,9 @@ Tahoe uses a few additional libraries which are included in this source
|
||||
distribution for convenience. These will be automatically built when you type
|
||||
'make', but if you have separate installations of them you may wish to modify
|
||||
the makefile to use those in preference to the included versions. They
|
||||
include Foolscap (a secure remote-object-invocation library), zfec (erasure
|
||||
coding), and a modified version of PyCrypto (enhanced to provide a faster
|
||||
CTR-mode API).
|
||||
include Foolscap (a secure remote-object-invocation library) and zfec
|
||||
(erasure coding). There are also pieces of PyCrypto copied into
|
||||
allmydata.Crypto, modified to provide a faster CTR-mode API.
|
||||
|
||||
|
||||
BUILDING:
|
||||
@ -173,11 +173,10 @@ Running-In-Place Way. Choose one:
|
||||
|
||||
The Python Way is to execute "setup.py install" for each Python package.
|
||||
|
||||
You'll need to run "setup.py install" five separate times, one for each of
|
||||
the five subpackages (allmydata, allmydata.Crypto, foolscap, simplejson,
|
||||
and zfec).
|
||||
You'll need to run "setup.py install" four separate times, one for each of
|
||||
the four subpackages (allmydata, foolscap, simplejson, and zfec).
|
||||
|
||||
for PACKAGE in zfec Crypto foolscap simplejson; do
|
||||
for PACKAGE in zfec foolscap simplejson; do
|
||||
cd src/${PACKAGE} && python setup.py install && cd ../..
|
||||
done
|
||||
|
||||
|
@ -6,13 +6,9 @@ A brief map to where the code lives in this distribution:
|
||||
src/zfec: the erasure-coding library, turns data into shares and back again.
|
||||
When installed, this provides the 'zfec' package.
|
||||
|
||||
src/Crypto: a modified version of PyCrypto, which includes a patch to
|
||||
greatly improve the speed of CTR mode, which unfortunately makes
|
||||
it incompatible with the normal version of PyCrypto. When
|
||||
installed, this provides the 'allmydata.Crypto' package.
|
||||
|
||||
src/allmydata: the bulk of the code for this project. When installed, this
|
||||
provides the 'allmydata' package
|
||||
provides the 'allmydata' package. This includes a few pieces
|
||||
copied from the PyCrypto package, in allmydata/Crypto/* .
|
||||
|
||||
Within src/allmydata/ :
|
||||
|
||||
|
@ -12,7 +12,6 @@ STAGING_DIR=$(CURDIR)/debian/allmydata-tahoe
|
||||
install/allmydata-tahoe::
|
||||
mkdir -pm755 $(STAGING_DIR)
|
||||
cd src/zfec && python setup.py install --single-version-externally-managed --root=$(STAGING_DIR)
|
||||
cd src/Crypto && python setup.py install --root=$(STAGING_DIR)
|
||||
python setup.py install --root=$(STAGING_DIR)
|
||||
|
||||
dh_pycentral
|
||||
|
@ -11,7 +11,6 @@ PREFIX=$(shell pwd)/debian/allmydata-tahoe/usr
|
||||
|
||||
build/allmydata-tahoe::
|
||||
cd src/zfec && python2.4 setup.py install --single-version-externally-managed --root=$(PREFIX)/..
|
||||
cd src/Crypto && python2.4 setup.py install --prefix=$(PREFIX)
|
||||
python2.4 setup.py install --prefix=$(PREFIX)
|
||||
|
||||
clean::
|
||||
|
26
setup.py
26
setup.py
@ -65,24 +65,38 @@ if os.path.exists(VERSIONFILE):
|
||||
print "unable to find version in version.py"
|
||||
raise RuntimeError("if version.py exists, it must be well-formed")
|
||||
|
||||
setup(name='allmydata-tahoe',
|
||||
version=verstr,
|
||||
description='secure, distributed storage grid',
|
||||
long_description="""Welcome to the AllMyData "tahoe" project. This project implements a
|
||||
|
||||
LONG_DESCRIPTION=\
|
||||
"""Welcome to the AllMyData "tahoe" project. This project implements a
|
||||
secure, distributed, fault-tolerant storage grid.
|
||||
|
||||
The basic idea is that the data in this storage grid is spread over all
|
||||
participating nodes, using an algorithm that can recover the data even if a
|
||||
majority of the nodes are no longer available.""",
|
||||
majority of the nodes are no longer available."""
|
||||
|
||||
setup(name='allmydata-tahoe',
|
||||
version=verstr,
|
||||
description='secure, distributed storage grid',
|
||||
long_description=LONG_DESCRIPTION,
|
||||
author='Allmydata, Inc.',
|
||||
author_email='tahoe-dev@allmydata.org',
|
||||
url='http://allmydata.org/',
|
||||
license='GNU GPL',
|
||||
packages=["allmydata", "allmydata.test", "allmydata.util",
|
||||
"allmydata.scripts",],
|
||||
"allmydata.scripts",
|
||||
"allmydata.Crypto", "allmydata.Crypto.Cipher",
|
||||
"allmydata.Crypto.Hash", "allmydata.Crypto.Util"],
|
||||
package_dir={ "allmydata": "src/allmydata",},
|
||||
scripts = ["bin/allmydata-tahoe"],
|
||||
package_data={ 'allmydata': ['web/*.xhtml', 'web/*.html', 'web/*.css'] },
|
||||
classifiers=trove_classifiers,
|
||||
test_suite="allmydata.test",
|
||||
ext_modules=[
|
||||
Extension("allmydata.Crypto.Cipher.AES",
|
||||
include_dirs=["src/allmydata/Crypto"],
|
||||
sources=["src/allmydata/Crypto/AES.c"]),
|
||||
Extension("allmydata.Crypto.Hash.SHA256",
|
||||
include_dirs=["src/allmydata/Crypto"],
|
||||
sources=["src/allmydata/Crypto/SHA256.c"]),
|
||||
],
|
||||
)
|
||||
|
@ -1,34 +0,0 @@
|
||||
Acknowledgements
|
||||
----------------
|
||||
|
||||
This list is sorted in alphabetical order, and is probably incomplete.
|
||||
I'd like to thank everybody who contributed in any way, with code, bug
|
||||
reports, and comments.
|
||||
|
||||
--amk
|
||||
|
||||
Tim Berners-Lee
|
||||
Ian Bicking
|
||||
Joris Bontje
|
||||
Antoon Bosselaers
|
||||
Andrea Bottoni
|
||||
Andrew Eland
|
||||
Philippe Frycia
|
||||
Peter Gutmann
|
||||
Hirendra Hindocha
|
||||
Nikhil Jhingan
|
||||
Piers Lauder
|
||||
M.-A. Lemburg
|
||||
Wim Lewis
|
||||
Mark Moraes
|
||||
Lim Chee Siang
|
||||
Bryan Olson
|
||||
Wallace Owen
|
||||
Colin Plumb
|
||||
James P. Rutledge
|
||||
Matt Schreiner
|
||||
Peter Simmons
|
||||
Paul Swartz
|
||||
Kevin M. Turner
|
||||
Eric Young
|
||||
|
@ -1,316 +0,0 @@
|
||||
|
||||
2.0.1
|
||||
=====
|
||||
|
||||
* Fix SHA256 and RIPEMD on AMD64 platform.
|
||||
* Deleted Demo/ directory.
|
||||
* Add PublicKey to Crypto.__all__
|
||||
|
||||
|
||||
2.0
|
||||
===
|
||||
|
||||
* Added SHA256 module contributed by Jeethu Rao, with test data
|
||||
from Taylor Boon.
|
||||
|
||||
* Fixed AES.c compilation problems with Borland C.
|
||||
(Contributed by Jeethu Rao.)
|
||||
|
||||
* Fix ZeroDivisionErrors on Windows, caused by the system clock
|
||||
not having enough resolution.
|
||||
|
||||
* Fix 2.1/2.2-incompatible use of (key not in dict),
|
||||
pointed out by Ian Bicking.
|
||||
|
||||
* Fix FutureWarning in Crypto.Util.randpool, noted by James P Rutledge.
|
||||
|
||||
|
||||
1.9alpha6
|
||||
=========
|
||||
|
||||
* Util.number.getPrime() would inadvertently round off the bit
|
||||
size; if you asked for a 129-bit prime or 135-bit prime, you
|
||||
got a 128-bit prime.
|
||||
|
||||
* Added Util/test/prime_speed.py to measure the speed of prime
|
||||
generation, and PublicKey/test/rsa_speed.py to measure
|
||||
the speed of RSA operations.
|
||||
|
||||
* Merged the _rsa.c and _dsa.c files into a single accelerator
|
||||
module, _fastmath.c.
|
||||
|
||||
* Speed improvements: Added fast isPrime() function to _fastmath,
|
||||
cutting the time to generate a 1024-bit prime by a factor of 10.
|
||||
Optimized the C version of RSA decryption to use a longer series
|
||||
of operations that's roughly 3x faster than a single
|
||||
exponentiation. (Contributed by Joris Bontje.)
|
||||
|
||||
* Added support to RSA key objects for blinding and unblinding
|
||||
data. (Contributed by Joris Bontje.)
|
||||
|
||||
* Simplified RSA key generation: hard-wired the encryption
|
||||
exponent to 65537 instead of generating a random prime;
|
||||
generate prime factors in a loop until the product
|
||||
is large enough.
|
||||
|
||||
* Renamed cansign(), canencrypt(), hasprivate(), to
|
||||
can_sign, can_encrypt, has_private. If people shriek about
|
||||
this change very loudly, I'll add aliases for the old method
|
||||
names that log a warning and call the new method.
|
||||
|
||||
|
||||
1.9alpha5
|
||||
=========
|
||||
|
||||
* Many randpool changes. RandomPool now has a
|
||||
randomize(N:int) method that can be called to get N
|
||||
bytes of entropy for the pool (N defaults to 0,
|
||||
which 'fills up' the pool's entropy) KeyboardRandom
|
||||
overloads this method.
|
||||
|
||||
* Added src/winrand.c for Crypto.Util.winrandom and
|
||||
now use winrandom for _randomize if possible.
|
||||
(Calls Windows CryptoAPI CryptGenRandom)
|
||||
|
||||
* Several additional places for stirring the pool,
|
||||
capturing inter-event entropy when reading/writing,
|
||||
stirring before and after saves.
|
||||
|
||||
* RandomPool.add_event now returns the number of
|
||||
estimated bits of added entropy, rather than the
|
||||
pool entropy itself (since the pool entropy is
|
||||
capped at the number of bits in the pool)
|
||||
|
||||
* Moved termios code from KeyboardRandomPool into a
|
||||
KeyboardEntry class, provided a version for Windows
|
||||
using msvcrt.
|
||||
|
||||
* Fix randpool.py crash on machines with poor timer resolution.
|
||||
(Reported by Mark Moraes and others.)
|
||||
|
||||
* If the GNU GMP library is available, two C extensions will be
|
||||
compiled to speed up RSA and DSA operations. (Contributed by
|
||||
Paul Swartz.)
|
||||
|
||||
* DES3 with a 24-byte key was broken; now fixed.
|
||||
(Patch by Philippe Frycia.)
|
||||
|
||||
|
||||
1.9alpha4
|
||||
=========
|
||||
|
||||
* Fix compilation problem on Windows.
|
||||
|
||||
* HMAC.py fixed to work with pre-2.2 Pythons
|
||||
|
||||
* setup.py now dies if built with Python 1.x
|
||||
|
||||
|
||||
1.9alpha3
|
||||
=========
|
||||
|
||||
* Fix a ref-counting bug that caused core dumps.
|
||||
(Reported by Piers Lauder and an anonymous SF poster.)
|
||||
|
||||
|
||||
1.9alpha2
|
||||
=========
|
||||
|
||||
* (Backwards incompatible) The old Crypto.Hash.HMAC module is
|
||||
gone, replaced by a copy of hmac.py from Python 2.2's standard
|
||||
library. It will display a warning on interpreter versions
|
||||
older than 2.2.
|
||||
|
||||
* (Backwards incompatible) Restored the Crypto.Protocol package,
|
||||
and modernized and tidied up the two modules in it,
|
||||
AllOrNothing.py and Chaffing.py, renaming various methods
|
||||
and changing the interface.
|
||||
|
||||
* (Backwards incompatible) Changed the function names in
|
||||
Crypto.Util.RFC1751.
|
||||
|
||||
* Restored the Crypto.PublicKey package at user request. I
|
||||
think I'll leave it in the package and warn about it in the
|
||||
documentation. I hope that eventually I can point to
|
||||
someone else's better public-key code, and at that point I
|
||||
may insert warnings and begin the process of deprecating
|
||||
this code.
|
||||
|
||||
* Fix use of a Python 2.2 C function, replacing it with a
|
||||
2.1-compatible equivalent. (Bug report and patch by Andrew
|
||||
Eland.)
|
||||
|
||||
* Fix endianness bugs that caused test case failures on Sparc,
|
||||
PPC, and doubtless other platforms.
|
||||
|
||||
* Fixed compilation problem on FreeBSD and MacOS X.
|
||||
|
||||
* Expanded the test suite (requires Sancho, from
|
||||
http://www.mems-exchange.org/software/sancho/)
|
||||
|
||||
* Added lots of docstrings, so 'pydoc Crypto' now produces
|
||||
helpful output. (Open question: maybe *all* of the documentation
|
||||
should be moved into docstrings?)
|
||||
|
||||
* Make test.py automatically add the build/* directory to sys.path.
|
||||
|
||||
* Removed 'inline' declaration from C functions. Some compilers
|
||||
don't support it, and Python's pyconfig.h no longer tells you whether
|
||||
it's supported or not. After this change, some ciphers got slower,
|
||||
but others got faster.
|
||||
|
||||
* The C-level API has been changed to reduce the amount of
|
||||
memory-to-memory copying. This makes the code neater, but
|
||||
had ambiguous performance effects; again, some ciphers got slower
|
||||
and others became faster. Probably this is due to my compiler
|
||||
optimizing slightly worse or better as a result.
|
||||
|
||||
* Moved C source implementations into src/ from block/, hash/,
|
||||
and stream/. Having Hash/ and hash/ directories causes problems
|
||||
on case-insensitive filesystems such as Mac OS.
|
||||
|
||||
* Cleaned up the C code for the extensions.
|
||||
|
||||
|
||||
1.9alpha1
|
||||
=========
|
||||
|
||||
* Added Crypto.Cipher.AES.
|
||||
|
||||
* Added the CTR mode and the variable-sized CFB mode from the
|
||||
NIST standard on feedback modes.
|
||||
|
||||
* Removed Diamond, HAVAL, MD5, Sapphire, SHA, and Skipjack. MD5
|
||||
and SHA are included with Python; the others are all of marginal
|
||||
usefulness in the real world.
|
||||
|
||||
* Renamed the module-level constants ECB, CFB, &c., to MODE_ECB,
|
||||
MODE_CFB, as part of making the block encryption modules
|
||||
compliant with PEP 272. (I'm not sure about this change;
|
||||
if enough users complain about it, I might back it out.)
|
||||
|
||||
* Made the hashing modules compliant with PEP 247 (not backward
|
||||
compatible -- the major changes are that the constructor is now
|
||||
MD2.new and not MD2.MD2, and the size of the digest is now
|
||||
given as 'digest_size', not 'digestsize'.
|
||||
|
||||
* The Crypto.PublicKey package is no longer installed; the
|
||||
interfaces are all wrong, and I have no idea what the right
|
||||
interfaces should be.
|
||||
|
||||
|
||||
1.1alpha2
|
||||
=========
|
||||
* Most importantly, the distribution has been broken into two
|
||||
parts: exportable, and export-controlled. The exportable part
|
||||
contains all the hashing algorithms, signature-only public key
|
||||
algorithms, chaffing & winnowing, random number generation, various
|
||||
utility modules, and the documentation.
|
||||
|
||||
The export-controlled part contains public-key encryption
|
||||
algorithms such as RSA and ElGamal, and bulk encryption algorithms
|
||||
like DES, IDEA, or Skipjack. Getting this code still requires that
|
||||
you go through an access control CGI script, and denies you access if
|
||||
you're outside the US or Canada.
|
||||
|
||||
* Added the RIPEMD hashing algorithm. (Contributed by
|
||||
Hirendra Hindocha.)
|
||||
|
||||
* Implemented the recently declassified Skipjack block
|
||||
encryption algorithm. My implementation runs at 864 K/sec on a
|
||||
PII/266, which isn't particularly fast, but you're probably better off
|
||||
using another algorithm anyway. :)
|
||||
|
||||
* A simple XOR cipher has been added, mostly for use by the
|
||||
chaffing/winnowing code. (Contributed by Barry Warsaw.)
|
||||
|
||||
* Added Protocol.Chaffing and Hash.HMAC.py. (Contributed by
|
||||
Barry Warsaw.)
|
||||
|
||||
Protocol.Chaffing implements chaffing and winnowing, recently
|
||||
proposed by R. Rivest, which hides a message (the wheat) by adding
|
||||
many noise messages to it (the chaff). The chaff can be discarded by
|
||||
the receiver through a message authentication code. The neat thing
|
||||
about this is that it allows secret communication without actually
|
||||
having an encryption algorithm, and therefore this falls within the
|
||||
exportable subset.
|
||||
|
||||
* Tidied up randpool.py, and removed its use of a block
|
||||
cipher; this makes it work with only the export-controlled subset
|
||||
available.
|
||||
|
||||
* Various renamings and reorganizations, mostly internal.
|
||||
|
||||
|
||||
1.0.2
|
||||
=====
|
||||
|
||||
* Changed files to work with Python 1.5; everything has been
|
||||
re-arranged into a hierarchical package. (Not backward compatible.)
|
||||
The package organization is:
|
||||
Crypto.
|
||||
Hash.
|
||||
MD2, MD4, MD5, SHA, HAVAL
|
||||
Cipher.
|
||||
ARC2, ARC4, Blowfish, CAST, DES, DES3, Diamond,
|
||||
IDEA, RC5, Sapphire
|
||||
PublicKey.
|
||||
DSA, ElGamal, qNEW, RSA
|
||||
Util.
|
||||
number, randpool, RFC1751
|
||||
|
||||
Since this is backward-incompatible anyway, I also changed
|
||||
module names from all lower-case to mixed-case: diamond -> Diamond,
|
||||
rc5 -> RC5, etc. That had been an annoying inconsistency for a while.
|
||||
|
||||
* Added CAST5 module contributed by <wiml@hhhh.org>.
|
||||
|
||||
* Added qNEW digital signature algorithm (from the digisign.py
|
||||
I advertised a while back). (If anyone would like to suggest new
|
||||
algorithms that should be implemented, please do; I think I've got
|
||||
everything that's really useful at the moment, but...)
|
||||
|
||||
* Support for keyword arguments has been added. This allowed
|
||||
removing the obnoxious key handling for Diamond and RC5, where the
|
||||
first few bytes of the key indicated the number of rounds to use, and
|
||||
various other parameters. Now you need only do something like:
|
||||
|
||||
from Crypto.Cipher import RC5
|
||||
obj = RC5.new(key, RC5.ECB, rounds=8)
|
||||
|
||||
(Not backward compatible.)
|
||||
|
||||
* Various function names have been changed, and parameter
|
||||
names altered. None of these were part of the public interface, so it
|
||||
shouldn't really matter much.
|
||||
|
||||
* Various bugs fixed, the test suite has been expanded, and
|
||||
the build process simplified.
|
||||
|
||||
* Updated the documentation accordingly.
|
||||
|
||||
|
||||
1.0.1
|
||||
=====
|
||||
|
||||
* Changed files to work with Python 1.4 .
|
||||
|
||||
* The DES and DES3 modules now automatically correct the
|
||||
parity of their keys.
|
||||
|
||||
* Added R. Rivest's DES test (see http://theory.lcs.mit.edu/~rivest/destest.txt)
|
||||
|
||||
|
||||
1.0.0
|
||||
=====
|
||||
|
||||
* REDOC III succumbed to differential cryptanalysis, and has
|
||||
been removed.
|
||||
|
||||
* The crypt and rotor modules have been dropped; they're still
|
||||
available in the standard Python distribution.
|
||||
|
||||
* The Ultra-Fast crypt() module has been placed in a separate
|
||||
distribution.
|
||||
|
||||
* Various bugs fixed.
|
@ -1,33 +0,0 @@
|
||||
"""Secret-key encryption algorithms.
|
||||
|
||||
Secret-key encryption algorithms transform plaintext in some way that
|
||||
is dependent on a key, producing ciphertext. This transformation can
|
||||
easily be reversed, if (and, hopefully, only if) one knows the key.
|
||||
|
||||
The encryption modules here all support the interface described in PEP
|
||||
272, "API for Block Encryption Algorithms".
|
||||
|
||||
If you don't know which algorithm to choose, use AES because it's
|
||||
standard and has undergone a fair bit of examination.
|
||||
|
||||
Crypto.Cipher.AES Advanced Encryption Standard
|
||||
Crypto.Cipher.ARC2 Alleged RC2
|
||||
Crypto.Cipher.ARC4 Alleged RC4
|
||||
Crypto.Cipher.Blowfish
|
||||
Crypto.Cipher.CAST
|
||||
Crypto.Cipher.DES The Data Encryption Standard. Very commonly used
|
||||
in the past, but today its 56-bit keys are too small.
|
||||
Crypto.Cipher.DES3 Triple DES.
|
||||
Crypto.Cipher.IDEA
|
||||
Crypto.Cipher.RC5
|
||||
Crypto.Cipher.XOR The simple XOR cipher.
|
||||
"""
|
||||
|
||||
__all__ = ['AES', 'ARC2', 'ARC4',
|
||||
'Blowfish', 'CAST', 'DES', 'DES3',
|
||||
'XOR'
|
||||
]
|
||||
|
||||
__revision__ = "$Id: __init__.py,v 1.7 2003/02/28 15:28:35 akuchling Exp $"
|
||||
|
||||
|
@ -1,29 +0,0 @@
|
||||
This directory contains demonstration files that use the modules
|
||||
included in the Python Cryptography Toolkit.
|
||||
|
||||
Note: These programs have version numbers of their own, which are not
|
||||
necessarily the same as the version number of the Toolkit package.
|
||||
|
||||
cipher Encrypt and decrypt sensitive files; type 'cipher -h'
|
||||
for a usage message.
|
||||
|
||||
voice Allows secure voice communication over a TCP/IP link.
|
||||
Currently this is Linux-specific; changes to make it
|
||||
run on other systems would be greatly appreciated.
|
||||
|
||||
RSAgen.py Generates a new RSA key. Demonstrates using
|
||||
randpool.py, and maintains a file of random data in
|
||||
"randseed". Requires that the IDEA and MD5 modules
|
||||
are installed.
|
||||
|
||||
testkey.py RSA public/private key pair used by example programs.
|
||||
|
||||
Secure importing of Python modules:
|
||||
|
||||
sign.py Sign all *.pyc files in a directory, using the
|
||||
key defined in testkey.py.
|
||||
|
||||
secimp.py Implementation of the secure 'import' command.
|
||||
|
||||
|
||||
|
@ -1,129 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
""" Example of Chaumian blinding """
|
||||
|
||||
import time, pprint, os, sha
|
||||
from allmydata.Crypto.PublicKey import *
|
||||
from allmydata.Crypto.Util.randpool import RandomPool
|
||||
from allmydata.Crypto.Util import number
|
||||
import cPickle as pickle
|
||||
|
||||
# Globals
|
||||
pool = RandomPool()
|
||||
pool.stir()
|
||||
|
||||
# use SHA-1 by default, if you want to use SHA-256, SHA-384 or SHA-512 you
|
||||
# need shax-py from http://philosophysw.com/software/
|
||||
digest = sha.sha
|
||||
|
||||
KEYSIZE = 1024
|
||||
KEYFILE = "tokenkey.pickle"
|
||||
HASHSIZE = sha.digestsize*8
|
||||
|
||||
### Initialization ###
|
||||
|
||||
if os.path.isfile(KEYFILE):
|
||||
# Load existing key """
|
||||
print "Server: load key..."
|
||||
ff = file(KEYFILE, 'r')
|
||||
key = pickle.load(ff)
|
||||
rsa = RSA.construct(key)
|
||||
else:
|
||||
# Generate an RSA key-pair of KEYSIZE bits and store the key
|
||||
print "Server: create key (will take a while, but only has to be done once)..."
|
||||
begintime=time.time()
|
||||
rsa=RSA.generate(KEYSIZE, pool.get_bytes)
|
||||
endtime=time.time()
|
||||
print "Server: Generate %d bit RSA key: %f s" % (KEYSIZE, endtime-begintime)
|
||||
|
||||
key = (rsa.n, rsa.e, rsa.d, rsa.p, rsa.q, rsa.u)
|
||||
ff = file(KEYFILE, 'w')
|
||||
pickle.dump(key, ff)
|
||||
|
||||
print "RSA key:"
|
||||
print "n = %s" % pprint.pformat(rsa.n) # Public key
|
||||
print "e = %s" % pprint.pformat(rsa.e) # Public key
|
||||
|
||||
print "d = %s" % pprint.pformat(rsa.d) # Private key
|
||||
# Values below are not really needed, but cause a big speedup since the Chinese Remainders Theorem can be used
|
||||
print "p = %s" % pprint.pformat(rsa.p) # Private key
|
||||
print "q = %s" % pprint.pformat(rsa.q) # Private key
|
||||
print "u = %s" % pprint.pformat(rsa.u) # Private key
|
||||
print
|
||||
|
||||
### Client ###
|
||||
|
||||
# Generate random tokenId of HASHSIZE bits
|
||||
tokenId = number.getRandomNumber(HASHSIZE, pool.get_bytes)
|
||||
|
||||
# Generate random blindingFactor of KEYSIZE-1 (so it can still be signed) bits
|
||||
while 1:
|
||||
blindingFactor = number.getRandomNumber(KEYSIZE-1, pool.get_bytes)
|
||||
# Verify that GCD(r, n) ==1
|
||||
if number.GCD(blindingFactor, rsa.n)==1:
|
||||
break
|
||||
|
||||
# Calculate the hash of the tokenId
|
||||
tokenHash = number.bytes_to_long(digest(number.long_to_bytes(tokenId)).digest())
|
||||
|
||||
print "tokenId = %s" % pprint.pformat(tokenId)
|
||||
print "blindingFactor = %s" % pprint.pformat(blindingFactor)
|
||||
print "tokenHash = %s" % pprint.pformat(tokenHash)
|
||||
print
|
||||
|
||||
# Blind the hashed tokenId with blindingFactor
|
||||
begintime=time.time()
|
||||
blindedToken=rsa.blind(tokenHash, blindingFactor)
|
||||
endtime=time.time()
|
||||
print "Client: Blinding: %f s" % (endtime-begintime)
|
||||
print "blindedToken = %s" % pprint.pformat(blindedToken)
|
||||
|
||||
# Send blindedToken to the server
|
||||
print "Client -> Server: blindedToken"
|
||||
print
|
||||
|
||||
### Server ###
|
||||
|
||||
# Sign the blindedToken
|
||||
begintime=time.time()
|
||||
blindedSignature=rsa.sign(blindedToken, None)[0]
|
||||
endtime=time.time()
|
||||
print "Server: Signing: %f s" % (endtime-begintime)
|
||||
print "blindedSignature = %s" % pprint.pformat(blindedSignature)
|
||||
|
||||
# Send the blindedSignature back to the client
|
||||
print "Server -> Client: blindedSignature"
|
||||
print
|
||||
|
||||
### Client ###
|
||||
|
||||
# Unblind the blindedSignature
|
||||
begintime=time.time()
|
||||
signature=rsa.unblind(blindedSignature, blindingFactor)
|
||||
endtime=time.time()
|
||||
print "Client: Unblinding: %f s" % (endtime-begintime)
|
||||
print "signature = %s" % pprint.pformat(signature)
|
||||
print
|
||||
|
||||
# Token is ready
|
||||
token = (tokenId, signature)
|
||||
print "Client: token = %s" % pprint.pformat(token)
|
||||
|
||||
print
|
||||
print "... user can now use the token..."
|
||||
print "Client -> Server: token"
|
||||
print
|
||||
|
||||
### Server ###
|
||||
|
||||
# Verify that the signature of hash(tokenId) is right
|
||||
begintime=time.time()
|
||||
v=rsa.verify(number.bytes_to_long(digest(number.long_to_bytes(token[0])).digest()), (token[1],))
|
||||
endtime=time.time()
|
||||
print "Server: Verifying: %f s" % (endtime-begintime)
|
||||
|
||||
if v:
|
||||
print "Server: SIGNATURE OK"
|
||||
else:
|
||||
print "Server: SIGNATURE NOT OK"
|
||||
|
@ -1,150 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# -*-Python-*-
|
||||
# Cipher 1.00
|
||||
#
|
||||
# Part of the Python Cryptography Toolkit
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
#
|
||||
|
||||
import sys, getopt, os
|
||||
|
||||
# Determine the name of this executable
|
||||
executable = os.path.basename(sys.argv[0])
|
||||
if executable=='': executable='cipher'
|
||||
cipher = '' # Unknown ciphering algorithm
|
||||
key = (0, '') # Empty key
|
||||
magic = 'ctx\001' # Magic string prefixed to the data
|
||||
NoInputFile = '' # Exceptions raised on file errors
|
||||
NoOutputFile = ''
|
||||
|
||||
def PrintUsage():
|
||||
print 'Usage: cipher [OPTIONS] file1 file2 ...'
|
||||
print '\n -c ciphername Force use of ciphername to encrypt/decrypt'
|
||||
print ' -k key Key to use for encryption/decryption'
|
||||
print '\nThe default cipher algorithm is IDEA; if no key is set on the command'
|
||||
print 'line, you will be prompted to enter a key.'
|
||||
print 'Files are read completely into memory, so do not try to encrypt'
|
||||
print 'very large files.'
|
||||
|
||||
def GenerateIV(length):
|
||||
import whrandom
|
||||
IV=''
|
||||
for i in range(0, length):
|
||||
IV=IV + chr(int(256*whrandom.random()))
|
||||
return IV
|
||||
|
||||
def Encipher(filename, cipher, key):
|
||||
if (cipher==''): cipher='IDEA'
|
||||
try:
|
||||
exec ('from Crypto.Cipher import '+cipher)
|
||||
module=eval(cipher)
|
||||
except ImportError:
|
||||
print executable+ ':', cipher, ': Cipher does not exist.'
|
||||
sys.exit(1)
|
||||
import Crypto.Hash.MD5
|
||||
try:
|
||||
input=open(filename, 'r')
|
||||
except IOError:
|
||||
raise NoInputFile
|
||||
try:
|
||||
output=open(filename+'.cip', 'w')
|
||||
except IOError:
|
||||
raise NoOutputFile, filename+'.cip'
|
||||
|
||||
if (key[0]==0):
|
||||
key=raw_input('Enter encryption key for '+ filename+ ':')
|
||||
else: key=key[1]
|
||||
key=Crypto.Hash.MD5.new(key).digest()
|
||||
IV=''
|
||||
for i in range(0, module.blocksize): IV=IV+'A'
|
||||
if (module.keysize==0):
|
||||
cipherobj=module.new(key, module.CBC, IV)
|
||||
else:
|
||||
cipherobj=module.new(key[0:module.keysize], module.CBC, IV)
|
||||
output.write(magic+cipher+'\0')
|
||||
data = GenerateIV(module.blocksize)
|
||||
filedata=input.read()
|
||||
data = data + magic + str(len(filedata))+'\0'+filename+'\0'
|
||||
data = data + filedata
|
||||
input.close()
|
||||
padding=module.blocksize - (len(data) % module.blocksize)
|
||||
for i in range(0, padding):
|
||||
data = data + chr(i)
|
||||
ciphertext=cipherobj.encrypt(data)
|
||||
output.write(ciphertext)
|
||||
output.close()
|
||||
|
||||
def Decipher(filename, cipher, key):
|
||||
import Crypto.Hash.MD5, string
|
||||
try:
|
||||
input=open(filename, 'r')
|
||||
except IOError:
|
||||
raise NoInputFile
|
||||
if (input.read(len(magic))!=magic):
|
||||
print executable+':', filename+': Does not seem to be a ciphered file'
|
||||
return
|
||||
t=''
|
||||
while (1):
|
||||
c=input.read(1)
|
||||
if (ord(c)==0): break
|
||||
t=t+c
|
||||
if (cipher==''): cipher=t
|
||||
try:
|
||||
from Crypto.Cipher import *
|
||||
module=eval(cipher)
|
||||
except ImportError:
|
||||
print executable+ ':', cipher, ': Cipher does not exist.'
|
||||
sys.exit(1)
|
||||
if (key[0]==0):
|
||||
key=raw_input('Enter encryption key for '+ filename+ ':')
|
||||
else: key=key[1]
|
||||
key=Crypto.Hash.MD5.new(key).digest()
|
||||
IV = ''
|
||||
for i in range(0, module.blocksize): IV=IV+'A'
|
||||
data=input.read()
|
||||
if (module.keysize==0):
|
||||
cipherobj=module.new(key, module.CBC, IV)
|
||||
else:
|
||||
cipherobj=module.new(key[0:module.keysize], module.CBC, IV)
|
||||
plain=cipherobj.decrypt(data) # Decrypt the data
|
||||
plain=plain[module.blocksize:] # Discard first block of random data
|
||||
if (plain[0:len(magic)]!=magic):
|
||||
print executable+':', filename+': Incorrect key or cipher algorithm'
|
||||
return
|
||||
else: plain=plain[len(magic):]
|
||||
i=string.find(plain, '\0')
|
||||
length=string.atoi(plain[0:i])
|
||||
j=string.find(plain, '\0', i+1)
|
||||
newfilename=plain[i+1:j]
|
||||
try:
|
||||
output=open(newfilename, 'w')
|
||||
except IOError:
|
||||
raise NoOutputFile, newfilename
|
||||
output.write(plain[j+1:j+1+length])
|
||||
output.close()
|
||||
|
||||
if len(sys.argv)==1: PrintUsage() ; sys.exit(0)
|
||||
|
||||
options, args=getopt.getopt(sys.argv[1:], 'c:k:hH')
|
||||
for opt in options:
|
||||
letter, param = opt
|
||||
if (letter=='-c'): cipher = param
|
||||
if (letter=='-k'): key = (1, param)
|
||||
if (letter=='-h' or letter=='-H'):
|
||||
PrintUsage()
|
||||
sys.exit(0)
|
||||
|
||||
for file in args:
|
||||
try:
|
||||
if (file[-4:]=='.cip'):
|
||||
Decipher(file, cipher, key)
|
||||
else:
|
||||
Encipher(file, cipher, key)
|
||||
except NoInputFile:
|
||||
print executable+ ':', file+ ': No such file.'
|
||||
except NoOutputFile, filename:
|
||||
print executable+ ':', filename+ ': Cannot open file'
|
||||
|
@ -1,334 +0,0 @@
|
||||
#!/usr/local/bin/python -Ou
|
||||
|
||||
""" enc - encrypt/decrypt files using one of SSLeay's ciphers.
|
||||
|
||||
Copyright (c) 1998 by Marc-Andre Lemburg; All Rights Reserved;
|
||||
mailto:mal@lemburg.com; See the documentation for further
|
||||
copyright information or contact the author.
|
||||
|
||||
DISCLAIMER & WARNING: This tool comes with NO WARRANTY. Use at
|
||||
YOUR OWN RISK. It may destroy data ! There is NO way to recover a
|
||||
forgotten pass phrase !
|
||||
"""
|
||||
import exceptions,os,string,time,sys
|
||||
from allmydata.CryptoWorld import Ciphers,Hashes,Utils
|
||||
from CommandLine import Application,SwitchOption,ArgumentOption
|
||||
|
||||
# Globals
|
||||
verbose = 0
|
||||
|
||||
# Maximum block size used for en/decryption
|
||||
MAX_BLOCKSIZE = 1024 * 1000
|
||||
|
||||
class OperationalError(exceptions.StandardError):
|
||||
pass
|
||||
|
||||
def filesize(file):
|
||||
|
||||
oldpos = file.tell()
|
||||
file.seek(0,2)
|
||||
size = file.tell()
|
||||
file.seek(oldpos)
|
||||
return size
|
||||
|
||||
def invisible_input(prompt='>>> '):
|
||||
|
||||
""" Adapted from the Python 1.5.1 docs example getpass()
|
||||
"""
|
||||
import termios,TERMIOS
|
||||
fd = sys.stdin.fileno()
|
||||
old = termios.tcgetattr(fd)
|
||||
new = termios.tcgetattr(fd)
|
||||
new[3] = new[3] & ~TERMIOS.ECHO # fix lflags
|
||||
try:
|
||||
termios.tcsetattr(fd, TERMIOS.TCSADRAIN, new)
|
||||
passwd = raw_input(prompt)
|
||||
finally:
|
||||
termios.tcsetattr(fd, TERMIOS.TCSADRAIN, old)
|
||||
print
|
||||
return passwd
|
||||
|
||||
def tempfile(filename='tmp',
|
||||
|
||||
maxint=sys.maxint,time=time.time,int=int,hex=hex,
|
||||
exists=os.path.exists):
|
||||
|
||||
""" Return a new filename for a temporary file (based on filename).
|
||||
"""
|
||||
temp = filename + '.' + hex(maxint % int(time())) + '.tmp'
|
||||
if not exists(temp):
|
||||
return temp
|
||||
# Ok, find an alternative name
|
||||
i = 0
|
||||
while 1:
|
||||
temp = '%s.%s-%i.tmp' % (filename,hex(maxint % int(time())),i)
|
||||
if not exists(temp):
|
||||
return temp
|
||||
i = i + 1
|
||||
|
||||
# Global key
|
||||
_key = ''
|
||||
|
||||
def get_cipher(name,check=0):
|
||||
|
||||
global _key
|
||||
|
||||
cc = getattr(Ciphers,name)
|
||||
keysize = cc.keysize
|
||||
if not _key:
|
||||
while 1:
|
||||
key1 = invisible_input('Please enter the key phrase: ')
|
||||
if check:
|
||||
key2 = invisible_input('Please reenter the phrase: ')
|
||||
if key1 != key2:
|
||||
print "Phrases don't match. Please start again..."
|
||||
continue
|
||||
if len(key1) == 0:
|
||||
print "Empty key phrase. Please start again..."
|
||||
else:
|
||||
break
|
||||
_key = key1
|
||||
key = _key
|
||||
# Fit key
|
||||
if keysize > 0:
|
||||
if len(key) < keysize:
|
||||
key = key + \
|
||||
'Do not change this string, it is important !'\
|
||||
[:keysize - len(key)]
|
||||
elif len(key) > keysize:
|
||||
key = key[:keysize]
|
||||
cipher = cc(key,Ciphers.CBC)
|
||||
return cipher
|
||||
|
||||
def reset_key():
|
||||
|
||||
global _key
|
||||
|
||||
_key = ''
|
||||
|
||||
###
|
||||
|
||||
def encrypt(filename,ciphername,overwrite=0):
|
||||
|
||||
if verbose:
|
||||
print 'Encrypting:',filename
|
||||
if filename[-4:] == '.enc':
|
||||
raise OperationalError,'already encrypted'
|
||||
if not os.path.isfile(filename):
|
||||
raise OperationalError,'not a file or not found'
|
||||
|
||||
# Check overwrites
|
||||
if os.path.exists(filename + '.enc'):
|
||||
if not overwrite:
|
||||
raise OperationalError,'would overwrite an existing file'
|
||||
elif os.path.samefile(filename, filename + '.enc'):
|
||||
raise OperationalError,'would overwrite the original file'
|
||||
|
||||
# Open plain file
|
||||
f = open(filename,'rb')
|
||||
size = filesize(f)
|
||||
if verbose:
|
||||
print ' total size: %i bytes' % size
|
||||
|
||||
# Open work file
|
||||
workfilename = tempfile(filename)
|
||||
out = open(workfilename,'wb')
|
||||
|
||||
try:
|
||||
# Init cipher and write header
|
||||
cipher = get_cipher(ciphername,check=1)
|
||||
out.write('enc %s %s %i\n' % \
|
||||
(repr(filename),ciphername,size))
|
||||
|
||||
# Init hash and blocksize
|
||||
hash = Hashes.MD5()
|
||||
blocksize = size
|
||||
if blocksize > MAX_BLOCKSIZE:
|
||||
blocksize = MAX_BLOCKSIZE
|
||||
blocksize = ((blocksize + cipher.blocksize - 1) / cipher.blocksize) \
|
||||
* cipher.blocksize
|
||||
|
||||
# Write the encrypted data in blocks
|
||||
bytesread = 0
|
||||
while bytesread < size:
|
||||
if verbose:
|
||||
print ' reading %i bytes...' % blocksize,
|
||||
block = f.read(blocksize)
|
||||
if verbose:
|
||||
print 'read %i bytes' % len(block)
|
||||
bytesread = bytesread + len(block)
|
||||
hash.update(block)
|
||||
if bytesread == size:
|
||||
# Final block
|
||||
offset = len(block) % cipher.blocksize
|
||||
if offset:
|
||||
padsize = cipher.blocksize - offset
|
||||
block = block + '\0'*padsize
|
||||
if verbose:
|
||||
print ' padding with %i bytes' % (padsize)
|
||||
encblock = cipher.encrypt(block)
|
||||
out.write(encblock)
|
||||
|
||||
# Write hash value
|
||||
hash_value = hash.digest()
|
||||
if verbose:
|
||||
print ' hash value:',repr(hash_value)
|
||||
out.write(hash_value)
|
||||
|
||||
# Copy work file to .enc file
|
||||
out.close()
|
||||
f.close()
|
||||
os.rename(workfilename,filename+'.enc')
|
||||
workfilename = None
|
||||
|
||||
finally:
|
||||
if workfilename:
|
||||
if not out.closed:
|
||||
out.close()
|
||||
os.remove(workfilename)
|
||||
|
||||
###
|
||||
|
||||
def decrypt(filename,overwrite=0):
|
||||
|
||||
if verbose:
|
||||
print 'Decrypting:',filename
|
||||
if filename[-4:] != '.enc':
|
||||
raise OperationalError,'decrypt a plain file'
|
||||
if not os.path.isfile(filename):
|
||||
raise OperationalError,'not a file or not found'
|
||||
|
||||
# Read header from cipher file
|
||||
f = open(filename,'rb')
|
||||
header = string.split(f.readline())
|
||||
if len(header) != 4:
|
||||
raise OperationalError,'wrong header format:'+ str(header)
|
||||
origfilename = eval(header[1])
|
||||
ciphername = header[2]
|
||||
size = string.atoi(header[3])
|
||||
if verbose:
|
||||
print ' total size: %i bytes' % size
|
||||
|
||||
# Check overwrites
|
||||
if os.path.exists(origfilename):
|
||||
if not overwrite:
|
||||
raise OperationalError,'would overwrite an existing file'
|
||||
elif os.path.samefile(origfilename, filename):
|
||||
raise OperationalError,'would overwrite the encrypted file'
|
||||
|
||||
# Open work file
|
||||
workfilename = tempfile(filename)
|
||||
out = open(workfilename,'wb')
|
||||
|
||||
try:
|
||||
|
||||
# Load cipher and init hash
|
||||
cipher = get_cipher(ciphername)
|
||||
hash = Hashes.MD5()
|
||||
|
||||
# Read the encrypted data in blocks
|
||||
blocksize = size
|
||||
if blocksize > MAX_BLOCKSIZE:
|
||||
blocksize = MAX_BLOCKSIZE
|
||||
blocksize = ((blocksize + cipher.blocksize - 1) / cipher.blocksize) \
|
||||
* cipher.blocksize
|
||||
bytesread = 0
|
||||
while bytesread < size:
|
||||
if size - bytesread < blocksize:
|
||||
# Read remaining data only
|
||||
blocksize = size - bytesread
|
||||
blocksize = ((blocksize + cipher.blocksize - 1) / \
|
||||
cipher.blocksize) * cipher.blocksize
|
||||
if verbose:
|
||||
print ' reading %i bytes...' % blocksize,
|
||||
encblock = f.read(blocksize)
|
||||
if verbose:
|
||||
print 'read %i bytes' % len(encblock)
|
||||
bytesread = bytesread + len(encblock)
|
||||
block = cipher.decrypt(encblock)
|
||||
if bytesread > size:
|
||||
# Depad
|
||||
padsize = bytesread - size
|
||||
block = block[:-padsize]
|
||||
if verbose:
|
||||
print ' depadded last block by %i bytes' % (padsize)
|
||||
hash.update(block)
|
||||
out.write(block)
|
||||
|
||||
# Check hash value
|
||||
hash_value = f.read(hash.digestsize)
|
||||
if verbose:
|
||||
print ' hash value:',repr(hash_value)
|
||||
if hash_value != hash.digest():
|
||||
raise OperationalError,'data corrupt'
|
||||
|
||||
# Copy workfile to origfile
|
||||
out.close()
|
||||
f.close()
|
||||
os.rename(workfilename,origfilename)
|
||||
workfilename = None
|
||||
|
||||
finally:
|
||||
if workfilename:
|
||||
if not out.closed:
|
||||
out.close()
|
||||
os.remove(workfilename)
|
||||
|
||||
###
|
||||
|
||||
class Encrypt(Application):
|
||||
|
||||
header = "File encryption utility using the SSLeay ciphers"
|
||||
|
||||
about = """\
|
||||
Encrypts or decrypts the files given on the command line. If no
|
||||
options are given the filenames extensions are taken as hint: '.enc'
|
||||
means encrypted, everything else not encrypted. The utility then goes
|
||||
and switches the state of the files. Overwriting of files only takes
|
||||
place in case the '-O' switch is set.
|
||||
|
||||
The following ciphers are supported:
|
||||
RC2, RC4, RC5, IDEA, Blowfish, DES, DES3, CAST
|
||||
|
||||
This tool comes with NO WARRANTY. Use at YOUR OWN RISK. It may destroy
|
||||
data ! There is NO way to recover a forgotten pass phrase !
|
||||
"""
|
||||
|
||||
options = [SwitchOption('-e', 'encrypt'),
|
||||
SwitchOption('-d', 'decyrpt'),
|
||||
SwitchOption('-a', 'use the same key for all files'),
|
||||
SwitchOption('-O', 'allow overwrites (use with care)'),
|
||||
ArgumentOption('-c', 'cipher to use', 'RC5'),
|
||||
]
|
||||
|
||||
def main(self):
|
||||
|
||||
overwrite = self.values['-O']
|
||||
ciphername = self.values['-c']
|
||||
samekey = self.values['-a']
|
||||
for file in self.files:
|
||||
if not samekey:
|
||||
reset_key()
|
||||
print '-'*78
|
||||
print 'Working on file:',file
|
||||
try:
|
||||
if self.values['-e']:
|
||||
encrypt(file,ciphername,overwrite)
|
||||
elif self.values['-d']:
|
||||
decrypt(file,overwrite)
|
||||
elif file[-4:] != '.enc':
|
||||
encrypt(file,ciphername,overwrite)
|
||||
else:
|
||||
decrypt(file,overwrite)
|
||||
except OperationalError,why:
|
||||
print '%s skipped -- %s' % (file,why)
|
||||
except IOError,(code,why):
|
||||
print '%s skipped -- %s' % (file,why)
|
||||
except os.error,why:
|
||||
print '%s skipped -- %s' % (file,why)
|
||||
except KeyboardInterrupt:
|
||||
print '*user break*'
|
||||
break
|
||||
|
||||
if __name__ == '__main__':
|
||||
Encrypt()
|
@ -1,24 +0,0 @@
|
||||
|
||||
This is a simple demonstration of adding an import hook that verifies
|
||||
a digital signature on a Python code object before allowing it to be
|
||||
imported. There are three files:
|
||||
|
||||
* sign.py, which signs all the *.pyc files in the directories
|
||||
listed on the command line. The contents of the .pyc file is stored
|
||||
along with the signature in a file whose name ends with .pys .
|
||||
|
||||
* secimp.py, which implements a secimport() function which
|
||||
will use *.pys files.
|
||||
|
||||
* testkey.py is the key used to sign and verify *.pys files.
|
||||
|
||||
To try it out:
|
||||
1. Run "sign.py ." to compile and sign all the *.py files in
|
||||
the current directory.
|
||||
|
||||
2. Run secimp.py from the command-line; it will try to
|
||||
securely import testkey.pys, which should succeed.
|
||||
|
||||
3. Fire up your favorite editor, and change a single byte in a
|
||||
string somewhere in testkey.pys. Run secimp.py again; it should raise
|
||||
an exception when the signature can't be verified.
|
@ -1,84 +0,0 @@
|
||||
#!/usr/local/bin/python
|
||||
|
||||
import sys ; sys.path = ['../../../'] + sys.path
|
||||
|
||||
import imp, os
|
||||
from sys import modules
|
||||
|
||||
# Secure import:
|
||||
def secimport(name, globals=None, locals=None, fromlist=None):
|
||||
# Fast path: let's see if it's already in sys.modules.
|
||||
# Two speed optimizations are worth mentioning:
|
||||
# - We use 'modules' instead of 'sys.modules'; this saves a
|
||||
# dictionary look-up per call.
|
||||
# - It's also faster to use a try-except statement than
|
||||
# to use modules.has_key(name) to check if it's there.
|
||||
try:
|
||||
return modules[name]
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
# See if it's a built-in module
|
||||
m = imp.init_builtin(name)
|
||||
if m:
|
||||
return m
|
||||
|
||||
# See if it's a frozen module
|
||||
m = imp.init_frozen(name)
|
||||
if m:
|
||||
return m
|
||||
|
||||
# Search the default path (i.e. sys.path).
|
||||
# If this raises an exception, the module is not found --
|
||||
# let the caller handle the exception.
|
||||
fp, pathname, (suffix, mode, type) = imp.find_module(name)
|
||||
|
||||
# See what we got...
|
||||
# Note that fp will be closed automatically when we return.
|
||||
|
||||
# Extensions are written in C, and can just be loaded.
|
||||
if type == imp.C_EXTENSION:
|
||||
return imp.load_dynamic(name, pathname)
|
||||
|
||||
# For a compiled or source file, we'll check if there is a *.pys file
|
||||
# present in the same directory.
|
||||
if type == imp.PY_COMPILED or type == imp.PY_SOURCE:
|
||||
root, ext = os.path.splitext(pathname)
|
||||
testfile = root + '.pys'
|
||||
try:
|
||||
print testfile
|
||||
secfile=open(testfile, 'rb')
|
||||
except IOError, tuple:
|
||||
if (tuple[0]==2): pass # Ignore 'file not found' error
|
||||
else: raise IOError, tuple
|
||||
else:
|
||||
# Check the signature (a signed hash of the code object).
|
||||
# We could sign the whole code object, but that would
|
||||
# require a huge key and would double the size of the
|
||||
# *.pys file.
|
||||
import marshal
|
||||
from allmydata.Crypto.Hash import MD5
|
||||
fp.close() # Close the original *.pyc file
|
||||
from testkey import * # Get the key for verification
|
||||
signature=marshal.load(secfile) # Read signature
|
||||
position=secfile.tell() # Save position
|
||||
data=secfile.read() # Read code object
|
||||
hash=MD5.new(data).digest() # Compute its hash value
|
||||
##print 'sigcheck:', key.verify(hash, signature)
|
||||
if (not key.verify(hash, signature)):
|
||||
raise ImportError, 'Signature check of '+ testfile + ' failed'
|
||||
secfile.seek(position) # Rewind pointer to the
|
||||
# beginning of the code object
|
||||
fp=secfile
|
||||
del secfile
|
||||
# Now we can happily import the compiled code object.
|
||||
return imp.load_compiled(name, pathname, fp)
|
||||
|
||||
# Shouldn't get here at all.
|
||||
raise ImportError, '%s: unknown module type (%d)' % (name, type)
|
||||
|
||||
if __name__=='__main__':
|
||||
# A sample invocation of the secure import looks like this:
|
||||
print 'Attempting secure import'
|
||||
r=secimport('testkey')
|
||||
print 'Secure import succeeded'
|
@ -1,46 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Using the public key defined in testkey.py, sign all *.pyc files in
|
||||
# the listed directories.
|
||||
|
||||
from testkey import *
|
||||
from allmydata.Crypto.Hash import MD5
|
||||
import os, glob, sys
|
||||
import marshal, compileall
|
||||
|
||||
filelist = []
|
||||
if (len(sys.argv)>1):
|
||||
for dir in sys.argv[1:]:
|
||||
dir=os.path.join(dir, '')
|
||||
compileall.compile_dir(dir)
|
||||
filelist=filelist + glob.glob(dir + '*.pyc')
|
||||
else:
|
||||
print "Usage: sign.py dir1 dir2 dir3 ..."
|
||||
print " All *.pyc files in the listed directories will be signed,"
|
||||
print "leaving the signatures in *.pys files."
|
||||
sys.exit(0)
|
||||
|
||||
if len(filelist)==0:
|
||||
print "No *.pyc files found"
|
||||
sys.exit(0)
|
||||
|
||||
for file in filelist:
|
||||
input=open(file, 'rb')
|
||||
try:
|
||||
os.unlink(file[:-4]+'.pys') # Delete any existing signed file
|
||||
except os.error, tuple:
|
||||
if (tuple[0]==2): pass # Ignore 'file not found' error
|
||||
else: raise os.error, tuple
|
||||
output=open(file[:-4]+'.pys', 'wb')
|
||||
data=input.read()
|
||||
hash=MD5.new(data).digest() # Compute hash of the code object
|
||||
K = "random bytes"
|
||||
signature=key.sign(hash, K) # Sign the hash value
|
||||
marshal.dump(signature, output) # Save signature to the file
|
||||
output.write(data) # Copy code object to signed file
|
||||
input.close()
|
||||
output.close()
|
||||
print os.path.basename(file)+ ' processed.'
|
||||
|
||||
|
||||
|
@ -1,41 +0,0 @@
|
||||
|
||||
import sys
|
||||
import allmydata.Crypto.PublicKey.DSA
|
||||
|
||||
key = allmydata.Crypto.PublicKey.DSA.construct((
|
||||
# y
|
||||
0x43E9162E224CBD1B66D7C27EB7E795392310B5E7AC6E0B1F60021F5E03F90E851CB7F76603FAE73907154371AE04EDBF0D9D557DF03488F34C18324B8DFEF5D2L,
|
||||
# g
|
||||
0x4D6DB63479E55D0BE31CF1BEA58AB9365FC5EA267FFCD8424B56390E6EE7DD9BF788F696EED8475516353E61F37B8441137FA4F8DC82A9F84FA52BCD37517C32L,
|
||||
# p
|
||||
0x8000011124427A59DC0AF8AC982B490C75B1B3E94042F50F500E0636391C6FCC8C13E628528B4B75E158618A34592D5A68CA684371F9678BBA54DD40C0020F25L,
|
||||
# q
|
||||
0x9B128544B02353FF961E1774D2FA94E52E078F5DL,
|
||||
# x
|
||||
0x991386B7B92C221E42B1386D61255F5C58FD79A7L,
|
||||
))
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Running this script directly will generate a new key and print it out
|
||||
from allmydata.Crypto.PublicKey import DSA
|
||||
from allmydata.Crypto.Util.randpool import KeyboardRandomPool
|
||||
|
||||
pool = KeyboardRandomPool(numbytes = 64)
|
||||
pool.randomize()
|
||||
|
||||
if len(sys.argv) == 2:
|
||||
keylen = int(sys.argv[1])
|
||||
elif len(sys.argv) == 1:
|
||||
keylen = 512
|
||||
else:
|
||||
print >>sys.stderr, 'Usage: '+sys.argv[0]+' [keylen]'
|
||||
sys.exit(1)
|
||||
key = DSA.generate(keylen, pool.get_bytes, sys.stdout.write)
|
||||
print "key = allmydata.Crypto.PublicKey.DSA.construct(("
|
||||
for field in key.keydata:
|
||||
print " #", field
|
||||
print " " + hex(getattr(key, field)) + ","
|
||||
print '))'
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,108 +0,0 @@
|
||||
"""HMAC (Keyed-Hashing for Message Authentication) Python module.
|
||||
|
||||
Implements the HMAC algorithm as described by RFC 2104.
|
||||
|
||||
This is just a copy of the Python 2.2 HMAC module, modified to work when
|
||||
used on versions of Python before 2.2.
|
||||
"""
|
||||
|
||||
__revision__ = "$Id: HMAC.py,v 1.5 2002/07/25 17:19:02 z3p Exp $"
|
||||
|
||||
import string
|
||||
|
||||
def _strxor(s1, s2):
|
||||
"""Utility method. XOR the two strings s1 and s2 (must have same length).
|
||||
"""
|
||||
return "".join(map(lambda x, y: chr(ord(x) ^ ord(y)), s1, s2))
|
||||
|
||||
# The size of the digests returned by HMAC depends on the underlying
|
||||
# hashing module used.
|
||||
digest_size = None
|
||||
|
||||
class HMAC:
|
||||
"""RFC2104 HMAC class.
|
||||
|
||||
This supports the API for Cryptographic Hash Functions (PEP 247).
|
||||
"""
|
||||
|
||||
def __init__(self, key, msg = None, digestmod = None):
|
||||
"""Create a new HMAC object.
|
||||
|
||||
key: key for the keyed hash object.
|
||||
msg: Initial input for the hash, if provided.
|
||||
digestmod: A module supporting PEP 247. Defaults to the md5 module.
|
||||
"""
|
||||
if digestmod == None:
|
||||
import md5
|
||||
digestmod = md5
|
||||
|
||||
self.digestmod = digestmod
|
||||
self.outer = digestmod.new()
|
||||
self.inner = digestmod.new()
|
||||
try:
|
||||
self.digest_size = digestmod.digest_size
|
||||
except AttributeError:
|
||||
self.digest_size = len(self.outer.digest())
|
||||
|
||||
blocksize = 64
|
||||
ipad = "\x36" * blocksize
|
||||
opad = "\x5C" * blocksize
|
||||
|
||||
if len(key) > blocksize:
|
||||
key = digestmod.new(key).digest()
|
||||
|
||||
key = key + chr(0) * (blocksize - len(key))
|
||||
self.outer.update(_strxor(key, opad))
|
||||
self.inner.update(_strxor(key, ipad))
|
||||
if (msg):
|
||||
self.update(msg)
|
||||
|
||||
## def clear(self):
|
||||
## raise NotImplementedError, "clear() method not available in HMAC."
|
||||
|
||||
def update(self, msg):
|
||||
"""Update this hashing object with the string msg.
|
||||
"""
|
||||
self.inner.update(msg)
|
||||
|
||||
def copy(self):
|
||||
"""Return a separate copy of this hashing object.
|
||||
|
||||
An update to this copy won't affect the original object.
|
||||
"""
|
||||
other = HMAC("")
|
||||
other.digestmod = self.digestmod
|
||||
other.inner = self.inner.copy()
|
||||
other.outer = self.outer.copy()
|
||||
return other
|
||||
|
||||
def digest(self):
|
||||
"""Return the hash value of this hashing object.
|
||||
|
||||
This returns a string containing 8-bit data. The object is
|
||||
not altered in any way by this function; you can continue
|
||||
updating the object after calling this function.
|
||||
"""
|
||||
h = self.outer.copy()
|
||||
h.update(self.inner.digest())
|
||||
return h.digest()
|
||||
|
||||
def hexdigest(self):
|
||||
"""Like digest(), but returns a string of hexadecimal digits instead.
|
||||
"""
|
||||
return "".join([string.zfill(hex(ord(x))[2:], 2)
|
||||
for x in tuple(self.digest())])
|
||||
|
||||
def new(key, msg = None, digestmod = None):
|
||||
"""Create a new hashing object and return it.
|
||||
|
||||
key: The starting key for the hash.
|
||||
msg: if available, will immediately be hashed into the object's starting
|
||||
state.
|
||||
|
||||
You can now feed arbitrary strings into the object using its update()
|
||||
method, and can ask for the hash value at any time by calling its digest()
|
||||
method.
|
||||
"""
|
||||
return HMAC(key, msg, digestmod)
|
||||
|
@ -1,13 +0,0 @@
|
||||
|
||||
# Just use the MD5 module from the Python standard library
|
||||
|
||||
__revision__ = "$Id: MD5.py,v 1.4 2002/07/11 14:31:19 akuchling Exp $"
|
||||
|
||||
from md5 import *
|
||||
|
||||
import md5
|
||||
if hasattr(md5, 'digestsize'):
|
||||
digest_size = digestsize
|
||||
del digestsize
|
||||
del md5
|
||||
|
@ -1,11 +0,0 @@
|
||||
|
||||
# Just use the SHA module from the Python standard library
|
||||
|
||||
__revision__ = "$Id: SHA.py,v 1.4 2002/07/11 14:31:19 akuchling Exp $"
|
||||
|
||||
from sha import *
|
||||
import sha
|
||||
if hasattr(sha, 'digestsize'):
|
||||
digest_size = digestsize
|
||||
del digestsize
|
||||
del sha
|
@ -1,24 +0,0 @@
|
||||
"""Hashing algorithms
|
||||
|
||||
Hash functions take arbitrary strings as input, and produce an output
|
||||
of fixed size that is dependent on the input; it should never be
|
||||
possible to derive the input data given only the hash function's
|
||||
output. Hash functions can be used simply as a checksum, or, in
|
||||
association with a public-key algorithm, can be used to implement
|
||||
digital signatures.
|
||||
|
||||
The hashing modules here all support the interface described in PEP
|
||||
247, "API for Cryptographic Hash Functions".
|
||||
|
||||
Submodules:
|
||||
Crypto.Hash.HMAC RFC 2104: Keyed-Hashing for Message Authentication
|
||||
Crypto.Hash.MD2
|
||||
Crypto.Hash.MD4
|
||||
Crypto.Hash.MD5
|
||||
Crypto.Hash.RIPEMD
|
||||
Crypto.Hash.SHA
|
||||
"""
|
||||
|
||||
__all__ = ['HMAC', 'MD2', 'MD4', 'MD5', 'SHA', 'SHA256']
|
||||
__revision__ = "$Id: __init__.py,v 1.6 2003/12/19 14:24:25 akuchling Exp $"
|
||||
|
@ -1,63 +0,0 @@
|
||||
ACKS
|
||||
ChangeLog
|
||||
Cipher/__init__.py
|
||||
Doc/pycrypt.tex
|
||||
Hash/HMAC.py
|
||||
Hash/MD5.py
|
||||
Hash/SHA.py
|
||||
Hash/__init__.py
|
||||
LICENSE
|
||||
MANIFEST
|
||||
Protocol/AllOrNothing.py
|
||||
Protocol/Chaffing.py
|
||||
Protocol/__init__.py
|
||||
PublicKey/DSA.py
|
||||
PublicKey/ElGamal.py
|
||||
PublicKey/RSA.py
|
||||
PublicKey/__init__.py
|
||||
PublicKey/pubkey.py
|
||||
PublicKey/qNEW.py
|
||||
PublicKey/test/rsa_speed.py
|
||||
README
|
||||
TODO
|
||||
Util/RFC1751.py
|
||||
Util/__init__.py
|
||||
Util/number.py
|
||||
Util/randpool.py
|
||||
Util/test.py
|
||||
Util/test/prime_speed.py
|
||||
__init__.py
|
||||
setup.py
|
||||
src/AES.c
|
||||
src/ARC2.c
|
||||
src/ARC4.c
|
||||
src/Blowfish.c
|
||||
src/CAST.c
|
||||
src/DES.c
|
||||
src/DES3.c
|
||||
src/IDEA.c
|
||||
src/MD2.c
|
||||
src/MD4.c
|
||||
src/RC5.c
|
||||
src/RIPEMD.c
|
||||
src/SHA256.c
|
||||
src/XOR.c
|
||||
src/block_template.c
|
||||
src/cast5.c
|
||||
src/hash_template.c
|
||||
src/stream_template.c
|
||||
src/winrand.c
|
||||
src/_dsa.c
|
||||
src/_fastmath.c
|
||||
src/_rsa.c
|
||||
test.py
|
||||
test/template
|
||||
test/test_allornothing.py
|
||||
test/test_chaffing.py
|
||||
test/test_hashes.py
|
||||
test/test_hmac.py
|
||||
test/test_number.py
|
||||
test/test_publickey.py
|
||||
test/test_randpool.py
|
||||
test/test_rfc1751.py
|
||||
test/testdata.py
|
@ -1,18 +0,0 @@
|
||||
Metadata-Version: 1.0
|
||||
Name: pycrypto
|
||||
Version: 2.0.1
|
||||
Summary: Cryptographic modules for Python.
|
||||
Home-page: http://www.amk.ca/python/code/crypto
|
||||
Author: A.M. Kuchling
|
||||
Author-email: amk@amk.ca
|
||||
License: UNKNOWN
|
||||
Download-URL: http://www.amk.ca/files/python/crypto/pycrypto-2.0.1.tar.gz
|
||||
Description: UNKNOWN
|
||||
Platform: UNKNOWN
|
||||
Classifier: Development Status :: 4 - Beta
|
||||
Classifier: License :: Public Domain
|
||||
Classifier: Intended Audience :: Developers
|
||||
Classifier: Operating System :: Unix
|
||||
Classifier: Operating System :: Microsoft :: Windows
|
||||
Classifier: Operating System :: MacOS :: MacOS X
|
||||
Classifier: Topic :: Security :: Cryptography
|
@ -1,295 +0,0 @@
|
||||
"""This file implements all-or-nothing package transformations.
|
||||
|
||||
An all-or-nothing package transformation is one in which some text is
|
||||
transformed into message blocks, such that all blocks must be obtained before
|
||||
the reverse transformation can be applied. Thus, if any blocks are corrupted
|
||||
or lost, the original message cannot be reproduced.
|
||||
|
||||
An all-or-nothing package transformation is not encryption, although a block
|
||||
cipher algorithm is used. The encryption key is randomly generated and is
|
||||
extractable from the message blocks.
|
||||
|
||||
This class implements the All-Or-Nothing package transformation algorithm
|
||||
described in:
|
||||
|
||||
Ronald L. Rivest. "All-Or-Nothing Encryption and The Package Transform"
|
||||
http://theory.lcs.mit.edu/~rivest/fusion.pdf
|
||||
|
||||
"""
|
||||
|
||||
__revision__ = "$Id: AllOrNothing.py,v 1.8 2003/02/28 15:23:20 akuchling Exp $"
|
||||
|
||||
import operator
|
||||
import string
|
||||
from allmydata.Crypto.Util.number import bytes_to_long, long_to_bytes
|
||||
|
||||
|
||||
|
||||
class AllOrNothing:
|
||||
"""Class implementing the All-or-Nothing package transform.
|
||||
|
||||
Methods for subclassing:
|
||||
|
||||
_inventkey(key_size):
|
||||
Returns a randomly generated key. Subclasses can use this to
|
||||
implement better random key generating algorithms. The default
|
||||
algorithm is probably not very cryptographically secure.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, ciphermodule, mode=None, IV=None):
|
||||
"""AllOrNothing(ciphermodule, mode=None, IV=None)
|
||||
|
||||
ciphermodule is a module implementing the cipher algorithm to
|
||||
use. It must provide the PEP272 interface.
|
||||
|
||||
Note that the encryption key is randomly generated
|
||||
automatically when needed. Optional arguments mode and IV are
|
||||
passed directly through to the ciphermodule.new() method; they
|
||||
are the feedback mode and initialization vector to use. All
|
||||
three arguments must be the same for the object used to create
|
||||
the digest, and to undigest'ify the message blocks.
|
||||
"""
|
||||
|
||||
self.__ciphermodule = ciphermodule
|
||||
self.__mode = mode
|
||||
self.__IV = IV
|
||||
self.__key_size = ciphermodule.key_size
|
||||
if self.__key_size == 0:
|
||||
self.__key_size = 16
|
||||
|
||||
__K0digit = chr(0x69)
|
||||
|
||||
def digest(self, text):
|
||||
"""digest(text:string) : [string]
|
||||
|
||||
Perform the All-or-Nothing package transform on the given
|
||||
string. Output is a list of message blocks describing the
|
||||
transformed text, where each block is a string of bit length equal
|
||||
to the ciphermodule's block_size.
|
||||
"""
|
||||
|
||||
# generate a random session key and K0, the key used to encrypt the
|
||||
# hash blocks. Rivest calls this a fixed, publically-known encryption
|
||||
# key, but says nothing about the security implications of this key or
|
||||
# how to choose it.
|
||||
key = self._inventkey(self.__key_size)
|
||||
K0 = self.__K0digit * self.__key_size
|
||||
|
||||
# we need two cipher objects here, one that is used to encrypt the
|
||||
# message blocks and one that is used to encrypt the hashes. The
|
||||
# former uses the randomly generated key, while the latter uses the
|
||||
# well-known key.
|
||||
mcipher = self.__newcipher(key)
|
||||
hcipher = self.__newcipher(K0)
|
||||
|
||||
# Pad the text so that its length is a multiple of the cipher's
|
||||
# block_size. Pad with trailing spaces, which will be eliminated in
|
||||
# the undigest() step.
|
||||
block_size = self.__ciphermodule.block_size
|
||||
padbytes = block_size - (len(text) % block_size)
|
||||
text = text + ' ' * padbytes
|
||||
|
||||
# Run through the algorithm:
|
||||
# s: number of message blocks (size of text / block_size)
|
||||
# input sequence: m1, m2, ... ms
|
||||
# random key K' (`key' in the code)
|
||||
# Compute output sequence: m'1, m'2, ... m's' for s' = s + 1
|
||||
# Let m'i = mi ^ E(K', i) for i = 1, 2, 3, ..., s
|
||||
# Let m's' = K' ^ h1 ^ h2 ^ ... hs
|
||||
# where hi = E(K0, m'i ^ i) for i = 1, 2, ... s
|
||||
#
|
||||
# The one complication I add is that the last message block is hard
|
||||
# coded to the number of padbytes added, so that these can be stripped
|
||||
# during the undigest() step
|
||||
s = len(text) / block_size
|
||||
blocks = []
|
||||
hashes = []
|
||||
for i in range(1, s+1):
|
||||
start = (i-1) * block_size
|
||||
end = start + block_size
|
||||
mi = text[start:end]
|
||||
assert len(mi) == block_size
|
||||
cipherblock = mcipher.encrypt(long_to_bytes(i, block_size))
|
||||
mticki = bytes_to_long(mi) ^ bytes_to_long(cipherblock)
|
||||
blocks.append(mticki)
|
||||
# calculate the hash block for this block
|
||||
hi = hcipher.encrypt(long_to_bytes(mticki ^ i, block_size))
|
||||
hashes.append(bytes_to_long(hi))
|
||||
|
||||
# Add the padbytes length as a message block
|
||||
i = i + 1
|
||||
cipherblock = mcipher.encrypt(long_to_bytes(i, block_size))
|
||||
mticki = padbytes ^ bytes_to_long(cipherblock)
|
||||
blocks.append(mticki)
|
||||
|
||||
# calculate this block's hash
|
||||
hi = hcipher.encrypt(long_to_bytes(mticki ^ i, block_size))
|
||||
hashes.append(bytes_to_long(hi))
|
||||
|
||||
# Now calculate the last message block of the sequence 1..s'. This
|
||||
# will contain the random session key XOR'd with all the hash blocks,
|
||||
# so that for undigest(), once all the hash blocks are calculated, the
|
||||
# session key can be trivially extracted. Calculating all the hash
|
||||
# blocks requires that all the message blocks be received, thus the
|
||||
# All-or-Nothing algorithm succeeds.
|
||||
mtick_stick = bytes_to_long(key) ^ reduce(operator.xor, hashes)
|
||||
blocks.append(mtick_stick)
|
||||
|
||||
# we convert the blocks to strings since in Python, byte sequences are
|
||||
# always represented as strings. This is more consistent with the
|
||||
# model that encryption and hash algorithms always operate on strings.
|
||||
return map(long_to_bytes, blocks)
|
||||
|
||||
|
||||
def undigest(self, blocks):
|
||||
"""undigest(blocks : [string]) : string
|
||||
|
||||
Perform the reverse package transformation on a list of message
|
||||
blocks. Note that the ciphermodule used for both transformations
|
||||
must be the same. blocks is a list of strings of bit length
|
||||
equal to the ciphermodule's block_size.
|
||||
"""
|
||||
|
||||
# better have at least 2 blocks, for the padbytes package and the hash
|
||||
# block accumulator
|
||||
if len(blocks) < 2:
|
||||
raise ValueError, "List must be at least length 2."
|
||||
|
||||
# blocks is a list of strings. We need to deal with them as long
|
||||
# integers
|
||||
blocks = map(bytes_to_long, blocks)
|
||||
|
||||
# Calculate the well-known key, to which the hash blocks are
|
||||
# encrypted, and create the hash cipher.
|
||||
K0 = self.__K0digit * self.__key_size
|
||||
hcipher = self.__newcipher(K0)
|
||||
|
||||
# Since we have all the blocks (or this method would have been called
|
||||
# prematurely), we can calcualte all the hash blocks.
|
||||
hashes = []
|
||||
for i in range(1, len(blocks)):
|
||||
mticki = blocks[i-1] ^ i
|
||||
hi = hcipher.encrypt(long_to_bytes(mticki))
|
||||
hashes.append(bytes_to_long(hi))
|
||||
|
||||
# now we can calculate K' (key). remember the last block contains
|
||||
# m's' which we don't include here
|
||||
key = blocks[-1] ^ reduce(operator.xor, hashes)
|
||||
|
||||
# and now we can create the cipher object
|
||||
mcipher = self.__newcipher(long_to_bytes(key))
|
||||
block_size = self.__ciphermodule.block_size
|
||||
|
||||
# And we can now decode the original message blocks
|
||||
parts = []
|
||||
for i in range(1, len(blocks)):
|
||||
cipherblock = mcipher.encrypt(long_to_bytes(i, block_size))
|
||||
mi = blocks[i-1] ^ bytes_to_long(cipherblock)
|
||||
parts.append(mi)
|
||||
|
||||
# The last message block contains the number of pad bytes appended to
|
||||
# the original text string, such that its length was an even multiple
|
||||
# of the cipher's block_size. This number should be small enough that
|
||||
# the conversion from long integer to integer should never overflow
|
||||
padbytes = int(parts[-1])
|
||||
text = string.join(map(long_to_bytes, parts[:-1]), '')
|
||||
return text[:-padbytes]
|
||||
|
||||
def _inventkey(self, key_size):
|
||||
# TBD: Not a very secure algorithm. Eventually, I'd like to use JHy's
|
||||
# kernelrand module
|
||||
import time
|
||||
from allmydata.Crypto.Util import randpool
|
||||
# TBD: key_size * 2 to work around possible bug in RandomPool?
|
||||
pool = randpool.RandomPool(key_size * 2)
|
||||
while key_size > pool.entropy:
|
||||
pool.add_event()
|
||||
|
||||
# we now have enough entropy in the pool to get a key_size'd key
|
||||
return pool.get_bytes(key_size)
|
||||
|
||||
def __newcipher(self, key):
|
||||
if self.__mode is None and self.__IV is None:
|
||||
return self.__ciphermodule.new(key)
|
||||
elif self.__IV is None:
|
||||
return self.__ciphermodule.new(key, self.__mode)
|
||||
else:
|
||||
return self.__ciphermodule.new(key, self.__mode, self.__IV)
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
import getopt
|
||||
import base64
|
||||
|
||||
usagemsg = '''\
|
||||
Test module usage: %(program)s [-c cipher] [-l] [-h]
|
||||
|
||||
Where:
|
||||
--cipher module
|
||||
-c module
|
||||
Cipher module to use. Default: %(ciphermodule)s
|
||||
|
||||
--aslong
|
||||
-l
|
||||
Print the encoded message blocks as long integers instead of base64
|
||||
encoded strings
|
||||
|
||||
--help
|
||||
-h
|
||||
Print this help message
|
||||
'''
|
||||
|
||||
ciphermodule = 'AES'
|
||||
aslong = 0
|
||||
|
||||
def usage(code, msg=None):
|
||||
if msg:
|
||||
print msg
|
||||
print usagemsg % {'program': sys.argv[0],
|
||||
'ciphermodule': ciphermodule}
|
||||
sys.exit(code)
|
||||
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:],
|
||||
'c:l', ['cipher=', 'aslong'])
|
||||
except getopt.error, msg:
|
||||
usage(1, msg)
|
||||
|
||||
if args:
|
||||
usage(1, 'Too many arguments')
|
||||
|
||||
for opt, arg in opts:
|
||||
if opt in ('-h', '--help'):
|
||||
usage(0)
|
||||
elif opt in ('-c', '--cipher'):
|
||||
ciphermodule = arg
|
||||
elif opt in ('-l', '--aslong'):
|
||||
aslong = 1
|
||||
|
||||
# ugly hack to force __import__ to give us the end-path module
|
||||
module = __import__('allmydata.Crypto.Cipher.'+ciphermodule, None, None, ['new'])
|
||||
|
||||
a = AllOrNothing(module)
|
||||
print 'Original text:\n=========='
|
||||
print __doc__
|
||||
print '=========='
|
||||
msgblocks = a.digest(__doc__)
|
||||
print 'message blocks:'
|
||||
for i, blk in map(None, range(len(msgblocks)), msgblocks):
|
||||
# base64 adds a trailing newline
|
||||
print ' %3d' % i,
|
||||
if aslong:
|
||||
print bytes_to_long(blk)
|
||||
else:
|
||||
print base64.encodestring(blk)[:-1]
|
||||
#
|
||||
# get a new undigest-only object so there's no leakage
|
||||
b = AllOrNothing(module)
|
||||
text = b.undigest(msgblocks)
|
||||
if text == __doc__:
|
||||
print 'They match!'
|
||||
else:
|
||||
print 'They differ!'
|
@ -1,229 +0,0 @@
|
||||
"""This file implements the chaffing algorithm.
|
||||
|
||||
Winnowing and chaffing is a technique for enhancing privacy without requiring
|
||||
strong encryption. In short, the technique takes a set of authenticated
|
||||
message blocks (the wheat) and adds a number of chaff blocks which have
|
||||
randomly chosen data and MAC fields. This means that to an adversary, the
|
||||
chaff blocks look as valid as the wheat blocks, and so the authentication
|
||||
would have to be performed on every block. By tailoring the number of chaff
|
||||
blocks added to the message, the sender can make breaking the message
|
||||
computationally infeasible. There are many other interesting properties of
|
||||
the winnow/chaff technique.
|
||||
|
||||
For example, say Alice is sending a message to Bob. She packetizes the
|
||||
message and performs an all-or-nothing transformation on the packets. Then
|
||||
she authenticates each packet with a message authentication code (MAC). The
|
||||
MAC is a hash of the data packet, and there is a secret key which she must
|
||||
share with Bob (key distribution is an exercise left to the reader). She then
|
||||
adds a serial number to each packet, and sends the packets to Bob.
|
||||
|
||||
Bob receives the packets, and using the shared secret authentication key,
|
||||
authenticates the MACs for each packet. Those packets that have bad MACs are
|
||||
simply discarded. The remainder are sorted by serial number, and passed
|
||||
through the reverse all-or-nothing transform. The transform means that an
|
||||
eavesdropper (say Eve) must acquire all the packets before any of the data can
|
||||
be read. If even one packet is missing, the data is useless.
|
||||
|
||||
There's one twist: by adding chaff packets, Alice and Bob can make Eve's job
|
||||
much harder, since Eve now has to break the shared secret key, or try every
|
||||
combination of wheat and chaff packet to read any of the message. The cool
|
||||
thing is that Bob doesn't need to add any additional code; the chaff packets
|
||||
are already filtered out because their MACs don't match (in all likelihood --
|
||||
since the data and MACs for the chaff packets are randomly chosen it is
|
||||
possible, but very unlikely that a chaff MAC will match the chaff data). And
|
||||
Alice need not even be the party adding the chaff! She could be completely
|
||||
unaware that a third party, say Charles, is adding chaff packets to her
|
||||
messages as they are transmitted.
|
||||
|
||||
For more information on winnowing and chaffing see this paper:
|
||||
|
||||
Ronald L. Rivest, "Chaffing and Winnowing: Confidentiality without Encryption"
|
||||
http://theory.lcs.mit.edu/~rivest/chaffing.txt
|
||||
|
||||
"""
|
||||
|
||||
__revision__ = "$Id: Chaffing.py,v 1.7 2003/02/28 15:23:21 akuchling Exp $"
|
||||
|
||||
from allmydata.Crypto.Util.number import bytes_to_long
|
||||
|
||||
class Chaff:
|
||||
"""Class implementing the chaff adding algorithm.
|
||||
|
||||
Methods for subclasses:
|
||||
|
||||
_randnum(size):
|
||||
Returns a randomly generated number with a byte-length equal
|
||||
to size. Subclasses can use this to implement better random
|
||||
data and MAC generating algorithms. The default algorithm is
|
||||
probably not very cryptographically secure. It is most
|
||||
important that the chaff data does not contain any patterns
|
||||
that can be used to discern it from wheat data without running
|
||||
the MAC.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, factor=1.0, blocksper=1):
|
||||
"""Chaff(factor:float, blocksper:int)
|
||||
|
||||
factor is the number of message blocks to add chaff to,
|
||||
expressed as a percentage between 0.0 and 1.0. blocksper is
|
||||
the number of chaff blocks to include for each block being
|
||||
chaffed. Thus the defaults add one chaff block to every
|
||||
message block. By changing the defaults, you can adjust how
|
||||
computationally difficult it could be for an adversary to
|
||||
brute-force crack the message. The difficulty is expressed
|
||||
as:
|
||||
|
||||
pow(blocksper, int(factor * number-of-blocks))
|
||||
|
||||
For ease of implementation, when factor < 1.0, only the first
|
||||
int(factor*number-of-blocks) message blocks are chaffed.
|
||||
"""
|
||||
|
||||
if not (0.0<=factor<=1.0):
|
||||
raise ValueError, "'factor' must be between 0.0 and 1.0"
|
||||
if blocksper < 0:
|
||||
raise ValueError, "'blocksper' must be zero or more"
|
||||
|
||||
self.__factor = factor
|
||||
self.__blocksper = blocksper
|
||||
|
||||
|
||||
def chaff(self, blocks):
|
||||
"""chaff( [(serial-number:int, data:string, MAC:string)] )
|
||||
: [(int, string, string)]
|
||||
|
||||
Add chaff to message blocks. blocks is a list of 3-tuples of the
|
||||
form (serial-number, data, MAC).
|
||||
|
||||
Chaff is created by choosing a random number of the same
|
||||
byte-length as data, and another random number of the same
|
||||
byte-length as MAC. The message block's serial number is
|
||||
placed on the chaff block and all the packet's chaff blocks
|
||||
are randomly interspersed with the single wheat block. This
|
||||
method then returns a list of 3-tuples of the same form.
|
||||
Chaffed blocks will contain multiple instances of 3-tuples
|
||||
with the same serial number, but the only way to figure out
|
||||
which blocks are wheat and which are chaff is to perform the
|
||||
MAC hash and compare values.
|
||||
"""
|
||||
|
||||
chaffedblocks = []
|
||||
|
||||
# count is the number of blocks to add chaff to. blocksper is the
|
||||
# number of chaff blocks to add per message block that is being
|
||||
# chaffed.
|
||||
count = len(blocks) * self.__factor
|
||||
blocksper = range(self.__blocksper)
|
||||
for i, wheat in map(None, range(len(blocks)), blocks):
|
||||
# it shouldn't matter which of the n blocks we add chaff to, so for
|
||||
# ease of implementation, we'll just add them to the first count
|
||||
# blocks
|
||||
if i < count:
|
||||
serial, data, mac = wheat
|
||||
datasize = len(data)
|
||||
macsize = len(mac)
|
||||
addwheat = 1
|
||||
# add chaff to this block
|
||||
for j in blocksper:
|
||||
import sys
|
||||
chaffdata = self._randnum(datasize)
|
||||
chaffmac = self._randnum(macsize)
|
||||
chaff = (serial, chaffdata, chaffmac)
|
||||
# mix up the order, if the 5th bit is on then put the
|
||||
# wheat on the list
|
||||
if addwheat and bytes_to_long(self._randnum(16)) & 0x40:
|
||||
chaffedblocks.append(wheat)
|
||||
addwheat = 0
|
||||
chaffedblocks.append(chaff)
|
||||
if addwheat:
|
||||
chaffedblocks.append(wheat)
|
||||
else:
|
||||
# just add the wheat
|
||||
chaffedblocks.append(wheat)
|
||||
return chaffedblocks
|
||||
|
||||
def _randnum(self, size):
|
||||
# TBD: Not a very secure algorithm.
|
||||
# TBD: size * 2 to work around possible bug in RandomPool
|
||||
from allmydata.Crypto.Util import randpool
|
||||
import time
|
||||
pool = randpool.RandomPool(size * 2)
|
||||
while size > pool.entropy:
|
||||
pass
|
||||
|
||||
# we now have enough entropy in the pool to get size bytes of random
|
||||
# data... well, probably
|
||||
return pool.get_bytes(size)
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
text = """\
|
||||
We hold these truths to be self-evident, that all men are created equal, that
|
||||
they are endowed by their Creator with certain unalienable Rights, that among
|
||||
these are Life, Liberty, and the pursuit of Happiness. That to secure these
|
||||
rights, Governments are instituted among Men, deriving their just powers from
|
||||
the consent of the governed. That whenever any Form of Government becomes
|
||||
destructive of these ends, it is the Right of the People to alter or to
|
||||
abolish it, and to institute new Government, laying its foundation on such
|
||||
principles and organizing its powers in such form, as to them shall seem most
|
||||
likely to effect their Safety and Happiness.
|
||||
"""
|
||||
print 'Original text:\n=========='
|
||||
print text
|
||||
print '=========='
|
||||
|
||||
# first transform the text into packets
|
||||
blocks = [] ; size = 40
|
||||
for i in range(0, len(text), size):
|
||||
blocks.append( text[i:i+size] )
|
||||
|
||||
# now get MACs for all the text blocks. The key is obvious...
|
||||
print 'Calculating MACs...'
|
||||
from allmydata.Crypto.Hash import HMAC, SHA
|
||||
key = 'Jefferson'
|
||||
macs = [HMAC.new(key, block, digestmod=SHA).digest()
|
||||
for block in blocks]
|
||||
|
||||
assert len(blocks) == len(macs)
|
||||
|
||||
# put these into a form acceptable as input to the chaffing procedure
|
||||
source = []
|
||||
m = map(None, range(len(blocks)), blocks, macs)
|
||||
print m
|
||||
for i, data, mac in m:
|
||||
source.append((i, data, mac))
|
||||
|
||||
# now chaff these
|
||||
print 'Adding chaff...'
|
||||
c = Chaff(factor=0.5, blocksper=2)
|
||||
chaffed = c.chaff(source)
|
||||
|
||||
from base64 import encodestring
|
||||
|
||||
# print the chaffed message blocks. meanwhile, separate the wheat from
|
||||
# the chaff
|
||||
|
||||
wheat = []
|
||||
print 'chaffed message blocks:'
|
||||
for i, data, mac in chaffed:
|
||||
# do the authentication
|
||||
h = HMAC.new(key, data, digestmod=SHA)
|
||||
pmac = h.digest()
|
||||
if pmac == mac:
|
||||
tag = '-->'
|
||||
wheat.append(data)
|
||||
else:
|
||||
tag = ' '
|
||||
# base64 adds a trailing newline
|
||||
print tag, '%3d' % i, \
|
||||
repr(data), encodestring(mac)[:-1]
|
||||
|
||||
# now decode the message packets and check it against the original text
|
||||
print 'Undigesting wheat...'
|
||||
newtext = "".join(wheat)
|
||||
if newtext == text:
|
||||
print 'They match!'
|
||||
else:
|
||||
print 'They differ!'
|
@ -1,17 +0,0 @@
|
||||
|
||||
"""Cryptographic protocols
|
||||
|
||||
Implements various cryptographic protocols. (Don't expect to find
|
||||
network protocols here.)
|
||||
|
||||
Crypto.Protocol.AllOrNothing Transforms a message into a set of message
|
||||
blocks, such that the blocks can be
|
||||
recombined to get the message back.
|
||||
|
||||
Crypto.Protocol.Chaffing Takes a set of authenticated message blocks
|
||||
(the wheat) and adds a number of
|
||||
randomly generated blocks (the chaff).
|
||||
"""
|
||||
|
||||
__all__ = ['AllOrNothing', 'Chaffing']
|
||||
__revision__ = "$Id: __init__.py,v 1.4 2003/02/28 15:23:21 akuchling Exp $"
|
@ -1,238 +0,0 @@
|
||||
|
||||
#
|
||||
# DSA.py : Digital Signature Algorithm
|
||||
#
|
||||
# Part of the Python Cryptography Toolkit
|
||||
#
|
||||
# Distribute and use freely; there are no restrictions on further
|
||||
# dissemination and usage except those imposed by the laws of your
|
||||
# country of residence. This software is provided "as is" without
|
||||
# warranty of fitness for use or suitability for any purpose, express
|
||||
# or implied. Use at your own risk or not at all.
|
||||
#
|
||||
|
||||
__revision__ = "$Id: DSA.py,v 1.16 2004/05/06 12:52:54 akuchling Exp $"
|
||||
|
||||
from allmydata.Crypto.PublicKey.pubkey import *
|
||||
from allmydata.Crypto.Util import number
|
||||
from allmydata.Crypto.Util.number import bytes_to_long, long_to_bytes
|
||||
from allmydata.Crypto.Hash import SHA
|
||||
|
||||
try:
|
||||
from allmydata.Crypto.PublicKey import _fastmath
|
||||
except ImportError:
|
||||
_fastmath = None
|
||||
|
||||
class error (Exception):
|
||||
pass
|
||||
|
||||
def generateQ(randfunc):
|
||||
S=randfunc(20)
|
||||
hash1=SHA.new(S).digest()
|
||||
hash2=SHA.new(long_to_bytes(bytes_to_long(S)+1)).digest()
|
||||
q = bignum(0)
|
||||
for i in range(0,20):
|
||||
c=ord(hash1[i])^ord(hash2[i])
|
||||
if i==0:
|
||||
c=c | 128
|
||||
if i==19:
|
||||
c= c | 1
|
||||
q=q*256+c
|
||||
while (not isPrime(q)):
|
||||
q=q+2
|
||||
if pow(2,159L) < q < pow(2,160L):
|
||||
return S, q
|
||||
raise error, 'Bad q value generated'
|
||||
|
||||
def generate(bits, randfunc, progress_func=None):
|
||||
"""generate(bits:int, randfunc:callable, progress_func:callable)
|
||||
|
||||
Generate a DSA key of length 'bits', using 'randfunc' to get
|
||||
random data and 'progress_func', if present, to display
|
||||
the progress of the key generation.
|
||||
"""
|
||||
|
||||
if bits<160:
|
||||
raise error, 'Key length <160 bits'
|
||||
obj=DSAobj()
|
||||
# Generate string S and prime q
|
||||
if progress_func:
|
||||
progress_func('p,q\n')
|
||||
while (1):
|
||||
S, obj.q = generateQ(randfunc)
|
||||
n=(bits-1)/160
|
||||
C, N, V = 0, 2, {}
|
||||
b=(obj.q >> 5) & 15
|
||||
powb=pow(bignum(2), b)
|
||||
powL1=pow(bignum(2), bits-1)
|
||||
while C<4096:
|
||||
for k in range(0, n+1):
|
||||
V[k]=bytes_to_long(SHA.new(S+str(N)+str(k)).digest())
|
||||
W=V[n] % powb
|
||||
for k in range(n-1, -1, -1):
|
||||
W=(W<<160L)+V[k]
|
||||
X=W+powL1
|
||||
p=X-(X%(2*obj.q)-1)
|
||||
if powL1<=p and isPrime(p):
|
||||
break
|
||||
C, N = C+1, N+n+1
|
||||
if C<4096:
|
||||
break
|
||||
if progress_func:
|
||||
progress_func('4096 multiples failed\n')
|
||||
|
||||
obj.p = p
|
||||
power=(p-1)/obj.q
|
||||
if progress_func:
|
||||
progress_func('h,g\n')
|
||||
while (1):
|
||||
h=bytes_to_long(randfunc(bits)) % (p-1)
|
||||
g=pow(h, power, p)
|
||||
if 1<h<p-1 and g>1:
|
||||
break
|
||||
obj.g=g
|
||||
if progress_func:
|
||||
progress_func('x,y\n')
|
||||
while (1):
|
||||
x=bytes_to_long(randfunc(20))
|
||||
if 0 < x < obj.q:
|
||||
break
|
||||
obj.x, obj.y = x, pow(g, x, p)
|
||||
return obj
|
||||
|
||||
def construct(tuple):
|
||||
"""construct(tuple:(long,long,long,long)|(long,long,long,long,long)):DSAobj
|
||||
Construct a DSA object from a 4- or 5-tuple of numbers.
|
||||
"""
|
||||
obj=DSAobj()
|
||||
if len(tuple) not in [4,5]:
|
||||
raise error, 'argument for construct() wrong length'
|
||||
for i in range(len(tuple)):
|
||||
field = obj.keydata[i]
|
||||
setattr(obj, field, tuple[i])
|
||||
return obj
|
||||
|
||||
class DSAobj(pubkey):
|
||||
keydata=['y', 'g', 'p', 'q', 'x']
|
||||
|
||||
def _encrypt(self, s, Kstr):
|
||||
raise error, 'DSA algorithm cannot encrypt data'
|
||||
|
||||
def _decrypt(self, s):
|
||||
raise error, 'DSA algorithm cannot decrypt data'
|
||||
|
||||
def _sign(self, M, K):
|
||||
if (K<2 or self.q<=K):
|
||||
raise error, 'K is not between 2 and q'
|
||||
r=pow(self.g, K, self.p) % self.q
|
||||
s=(inverse(K, self.q)*(M+self.x*r)) % self.q
|
||||
return (r,s)
|
||||
|
||||
def _verify(self, M, sig):
|
||||
r, s = sig
|
||||
if r<=0 or r>=self.q or s<=0 or s>=self.q:
|
||||
return 0
|
||||
w=inverse(s, self.q)
|
||||
u1, u2 = (M*w) % self.q, (r*w) % self.q
|
||||
v1 = pow(self.g, u1, self.p)
|
||||
v2 = pow(self.y, u2, self.p)
|
||||
v = ((v1*v2) % self.p)
|
||||
v = v % self.q
|
||||
if v==r:
|
||||
return 1
|
||||
return 0
|
||||
|
||||
def size(self):
|
||||
"Return the maximum number of bits that can be handled by this key."
|
||||
return number.size(self.p) - 1
|
||||
|
||||
def has_private(self):
|
||||
"""Return a Boolean denoting whether the object contains
|
||||
private components."""
|
||||
if hasattr(self, 'x'):
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
def can_sign(self):
|
||||
"""Return a Boolean value recording whether this algorithm can generate signatures."""
|
||||
return 1
|
||||
|
||||
def can_encrypt(self):
|
||||
"""Return a Boolean value recording whether this algorithm can encrypt data."""
|
||||
return 0
|
||||
|
||||
def publickey(self):
|
||||
"""Return a new key object containing only the public information."""
|
||||
return construct((self.y, self.g, self.p, self.q))
|
||||
|
||||
object=DSAobj
|
||||
|
||||
generate_py = generate
|
||||
construct_py = construct
|
||||
|
||||
class DSAobj_c(pubkey):
|
||||
keydata = ['y', 'g', 'p', 'q', 'x']
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
|
||||
def __getattr__(self, attr):
|
||||
if attr in self.keydata:
|
||||
return getattr(self.key, attr)
|
||||
else:
|
||||
if self.__dict__.has_key(attr):
|
||||
self.__dict__[attr]
|
||||
else:
|
||||
raise AttributeError, '%s instance has no attribute %s' % (self.__class__, attr)
|
||||
|
||||
def __getstate__(self):
|
||||
d = {}
|
||||
for k in self.keydata:
|
||||
if hasattr(self.key, k):
|
||||
d[k]=getattr(self.key, k)
|
||||
return d
|
||||
|
||||
def __setstate__(self, state):
|
||||
y,g,p,q = state['y'], state['g'], state['p'], state['q']
|
||||
if not state.has_key('x'):
|
||||
self.key = _fastmath.dsa_construct(y,g,p,q)
|
||||
else:
|
||||
x = state['x']
|
||||
self.key = _fastmath.dsa_construct(y,g,p,q,x)
|
||||
|
||||
def _sign(self, M, K):
|
||||
return self.key._sign(M, K)
|
||||
|
||||
def _verify(self, M, (r, s)):
|
||||
return self.key._verify(M, r, s)
|
||||
|
||||
def size(self):
|
||||
return self.key.size()
|
||||
|
||||
def has_private(self):
|
||||
return self.key.has_private()
|
||||
|
||||
def publickey(self):
|
||||
return construct_c((self.key.y, self.key.g, self.key.p, self.key.q))
|
||||
|
||||
def can_sign(self):
|
||||
return 1
|
||||
|
||||
def can_encrypt(self):
|
||||
return 0
|
||||
|
||||
def generate_c(bits, randfunc, progress_func=None):
|
||||
obj = generate_py(bits, randfunc, progress_func)
|
||||
y,g,p,q,x = obj.y, obj.g, obj.p, obj.q, obj.x
|
||||
return construct_c((y,g,p,q,x))
|
||||
|
||||
def construct_c(tuple):
|
||||
key = apply(_fastmath.dsa_construct, tuple)
|
||||
return DSAobj_c(key)
|
||||
|
||||
if _fastmath:
|
||||
#print "using C version of DSA"
|
||||
generate = generate_c
|
||||
construct = construct_c
|
||||
error = _fastmath.error
|
@ -1,132 +0,0 @@
|
||||
#
|
||||
# ElGamal.py : ElGamal encryption/decryption and signatures
|
||||
#
|
||||
# Part of the Python Cryptography Toolkit
|
||||
#
|
||||
# Distribute and use freely; there are no restrictions on further
|
||||
# dissemination and usage except those imposed by the laws of your
|
||||
# country of residence. This software is provided "as is" without
|
||||
# warranty of fitness for use or suitability for any purpose, express
|
||||
# or implied. Use at your own risk or not at all.
|
||||
#
|
||||
|
||||
__revision__ = "$Id: ElGamal.py,v 1.9 2003/04/04 19:44:26 akuchling Exp $"
|
||||
|
||||
from allmydata.Crypto.PublicKey.pubkey import *
|
||||
from allmydata.Crypto.Util import number
|
||||
|
||||
class error (Exception):
|
||||
pass
|
||||
|
||||
# Generate an ElGamal key with N bits
|
||||
def generate(bits, randfunc, progress_func=None):
|
||||
"""generate(bits:int, randfunc:callable, progress_func:callable)
|
||||
|
||||
Generate an ElGamal key of length 'bits', using 'randfunc' to get
|
||||
random data and 'progress_func', if present, to display
|
||||
the progress of the key generation.
|
||||
"""
|
||||
obj=ElGamalobj()
|
||||
# Generate prime p
|
||||
if progress_func:
|
||||
progress_func('p\n')
|
||||
obj.p=bignum(getPrime(bits, randfunc))
|
||||
# Generate random number g
|
||||
if progress_func:
|
||||
progress_func('g\n')
|
||||
size=bits-1-(ord(randfunc(1)) & 63) # g will be from 1--64 bits smaller than p
|
||||
if size<1:
|
||||
size=bits-1
|
||||
while (1):
|
||||
obj.g=bignum(getPrime(size, randfunc))
|
||||
if obj.g < obj.p:
|
||||
break
|
||||
size=(size+1) % bits
|
||||
if size==0:
|
||||
size=4
|
||||
# Generate random number x
|
||||
if progress_func:
|
||||
progress_func('x\n')
|
||||
while (1):
|
||||
size=bits-1-ord(randfunc(1)) # x will be from 1 to 256 bits smaller than p
|
||||
if size>2:
|
||||
break
|
||||
while (1):
|
||||
obj.x=bignum(getPrime(size, randfunc))
|
||||
if obj.x < obj.p:
|
||||
break
|
||||
size = (size+1) % bits
|
||||
if size==0:
|
||||
size=4
|
||||
if progress_func:
|
||||
progress_func('y\n')
|
||||
obj.y = pow(obj.g, obj.x, obj.p)
|
||||
return obj
|
||||
|
||||
def construct(tuple):
|
||||
"""construct(tuple:(long,long,long,long)|(long,long,long,long,long)))
|
||||
: ElGamalobj
|
||||
Construct an ElGamal key from a 3- or 4-tuple of numbers.
|
||||
"""
|
||||
|
||||
obj=ElGamalobj()
|
||||
if len(tuple) not in [3,4]:
|
||||
raise error, 'argument for construct() wrong length'
|
||||
for i in range(len(tuple)):
|
||||
field = obj.keydata[i]
|
||||
setattr(obj, field, tuple[i])
|
||||
return obj
|
||||
|
||||
class ElGamalobj(pubkey):
|
||||
keydata=['p', 'g', 'y', 'x']
|
||||
|
||||
def _encrypt(self, M, K):
|
||||
a=pow(self.g, K, self.p)
|
||||
b=( M*pow(self.y, K, self.p) ) % self.p
|
||||
return ( a,b )
|
||||
|
||||
def _decrypt(self, M):
|
||||
if (not hasattr(self, 'x')):
|
||||
raise error, 'Private key not available in this object'
|
||||
ax=pow(M[0], self.x, self.p)
|
||||
plaintext=(M[1] * inverse(ax, self.p ) ) % self.p
|
||||
return plaintext
|
||||
|
||||
def _sign(self, M, K):
|
||||
if (not hasattr(self, 'x')):
|
||||
raise error, 'Private key not available in this object'
|
||||
p1=self.p-1
|
||||
if (GCD(K, p1)!=1):
|
||||
raise error, 'Bad K value: GCD(K,p-1)!=1'
|
||||
a=pow(self.g, K, self.p)
|
||||
t=(M-self.x*a) % p1
|
||||
while t<0: t=t+p1
|
||||
b=(t*inverse(K, p1)) % p1
|
||||
return (a, b)
|
||||
|
||||
def _verify(self, M, sig):
|
||||
v1=pow(self.y, sig[0], self.p)
|
||||
v1=(v1*pow(sig[0], sig[1], self.p)) % self.p
|
||||
v2=pow(self.g, M, self.p)
|
||||
if v1==v2:
|
||||
return 1
|
||||
return 0
|
||||
|
||||
def size(self):
|
||||
"Return the maximum number of bits that can be handled by this key."
|
||||
return number.size(self.p) - 1
|
||||
|
||||
def has_private(self):
|
||||
"""Return a Boolean denoting whether the object contains
|
||||
private components."""
|
||||
if hasattr(self, 'x'):
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
def publickey(self):
|
||||
"""Return a new key object containing only the public information."""
|
||||
return construct((self.p, self.g, self.y))
|
||||
|
||||
|
||||
object=ElGamalobj
|
@ -1,256 +0,0 @@
|
||||
#
|
||||
# RSA.py : RSA encryption/decryption
|
||||
#
|
||||
# Part of the Python Cryptography Toolkit
|
||||
#
|
||||
# Distribute and use freely; there are no restrictions on further
|
||||
# dissemination and usage except those imposed by the laws of your
|
||||
# country of residence. This software is provided "as is" without
|
||||
# warranty of fitness for use or suitability for any purpose, express
|
||||
# or implied. Use at your own risk or not at all.
|
||||
#
|
||||
|
||||
__revision__ = "$Id: RSA.py,v 1.20 2004/05/06 12:52:54 akuchling Exp $"
|
||||
|
||||
from allmydata.Crypto.PublicKey import pubkey
|
||||
from allmydata.Crypto.Util import number
|
||||
|
||||
try:
|
||||
from allmydata.Crypto.PublicKey import _fastmath
|
||||
except ImportError:
|
||||
_fastmath = None
|
||||
|
||||
class error (Exception):
|
||||
pass
|
||||
|
||||
def generate(bits, randfunc, progress_func=None):
|
||||
"""generate(bits:int, randfunc:callable, progress_func:callable)
|
||||
|
||||
Generate an RSA key of length 'bits', using 'randfunc' to get
|
||||
random data and 'progress_func', if present, to display
|
||||
the progress of the key generation.
|
||||
"""
|
||||
obj=RSAobj()
|
||||
|
||||
# Generate the prime factors of n
|
||||
if progress_func:
|
||||
progress_func('p,q\n')
|
||||
p = q = 1L
|
||||
while number.size(p*q) < bits:
|
||||
p = pubkey.getPrime(bits/2, randfunc)
|
||||
q = pubkey.getPrime(bits/2, randfunc)
|
||||
|
||||
# p shall be smaller than q (for calc of u)
|
||||
if p > q:
|
||||
(p, q)=(q, p)
|
||||
obj.p = p
|
||||
obj.q = q
|
||||
|
||||
if progress_func:
|
||||
progress_func('u\n')
|
||||
obj.u = pubkey.inverse(obj.p, obj.q)
|
||||
obj.n = obj.p*obj.q
|
||||
|
||||
obj.e = 65537L
|
||||
if progress_func:
|
||||
progress_func('d\n')
|
||||
obj.d=pubkey.inverse(obj.e, (obj.p-1)*(obj.q-1))
|
||||
|
||||
assert bits <= 1+obj.size(), "Generated key is too small"
|
||||
|
||||
return obj
|
||||
|
||||
def construct(tuple):
|
||||
"""construct(tuple:(long,) : RSAobj
|
||||
Construct an RSA object from a 2-, 3-, 5-, or 6-tuple of numbers.
|
||||
"""
|
||||
|
||||
obj=RSAobj()
|
||||
if len(tuple) not in [2,3,5,6]:
|
||||
raise error, 'argument for construct() wrong length'
|
||||
for i in range(len(tuple)):
|
||||
field = obj.keydata[i]
|
||||
setattr(obj, field, tuple[i])
|
||||
if len(tuple) >= 5:
|
||||
# Ensure p is smaller than q
|
||||
if obj.p>obj.q:
|
||||
(obj.p, obj.q)=(obj.q, obj.p)
|
||||
|
||||
if len(tuple) == 5:
|
||||
# u not supplied, so we're going to have to compute it.
|
||||
obj.u=pubkey.inverse(obj.p, obj.q)
|
||||
|
||||
return obj
|
||||
|
||||
class RSAobj(pubkey.pubkey):
|
||||
keydata = ['n', 'e', 'd', 'p', 'q', 'u']
|
||||
def _encrypt(self, plaintext, K=''):
|
||||
if self.n<=plaintext:
|
||||
raise error, 'Plaintext too large'
|
||||
return (pow(plaintext, self.e, self.n),)
|
||||
|
||||
def _decrypt(self, ciphertext):
|
||||
if (not hasattr(self, 'd')):
|
||||
raise error, 'Private key not available in this object'
|
||||
if self.n<=ciphertext[0]:
|
||||
raise error, 'Ciphertext too large'
|
||||
return pow(ciphertext[0], self.d, self.n)
|
||||
|
||||
def _sign(self, M, K=''):
|
||||
return (self._decrypt((M,)),)
|
||||
|
||||
def _verify(self, M, sig):
|
||||
m2=self._encrypt(sig[0])
|
||||
if m2[0]==M:
|
||||
return 1
|
||||
else: return 0
|
||||
|
||||
def _blind(self, M, B):
|
||||
tmp = pow(B, self.e, self.n)
|
||||
return (M * tmp) % self.n
|
||||
|
||||
def _unblind(self, M, B):
|
||||
tmp = pubkey.inverse(B, self.n)
|
||||
return (M * tmp) % self.n
|
||||
|
||||
def can_blind (self):
|
||||
"""can_blind() : bool
|
||||
Return a Boolean value recording whether this algorithm can
|
||||
blind data. (This does not imply that this
|
||||
particular key object has the private information required to
|
||||
to blind a message.)
|
||||
"""
|
||||
return 1
|
||||
|
||||
def size(self):
|
||||
"""size() : int
|
||||
Return the maximum number of bits that can be handled by this key.
|
||||
"""
|
||||
return number.size(self.n) - 1
|
||||
|
||||
def has_private(self):
|
||||
"""has_private() : bool
|
||||
Return a Boolean denoting whether the object contains
|
||||
private components.
|
||||
"""
|
||||
if hasattr(self, 'd'):
|
||||
return 1
|
||||
else: return 0
|
||||
|
||||
def publickey(self):
|
||||
"""publickey(): RSAobj
|
||||
Return a new key object containing only the public key information.
|
||||
"""
|
||||
return construct((self.n, self.e))
|
||||
|
||||
class RSAobj_c(pubkey.pubkey):
|
||||
keydata = ['n', 'e', 'd', 'p', 'q', 'u']
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
|
||||
def __getattr__(self, attr):
|
||||
if attr in self.keydata:
|
||||
return getattr(self.key, attr)
|
||||
else:
|
||||
if self.__dict__.has_key(attr):
|
||||
self.__dict__[attr]
|
||||
else:
|
||||
raise AttributeError, '%s instance has no attribute %s' % (self.__class__, attr)
|
||||
|
||||
def __getstate__(self):
|
||||
d = {}
|
||||
for k in self.keydata:
|
||||
if hasattr(self.key, k):
|
||||
d[k]=getattr(self.key, k)
|
||||
return d
|
||||
|
||||
def __setstate__(self, state):
|
||||
n,e = state['n'], state['e']
|
||||
if not state.has_key('d'):
|
||||
self.key = _fastmath.rsa_construct(n,e)
|
||||
else:
|
||||
d = state['d']
|
||||
if not state.has_key('q'):
|
||||
self.key = _fastmath.rsa_construct(n,e,d)
|
||||
else:
|
||||
p, q, u = state['p'], state['q'], state['u']
|
||||
self.key = _fastmath.rsa_construct(n,e,d,p,q,u)
|
||||
|
||||
def _encrypt(self, plain, K):
|
||||
return (self.key._encrypt(plain),)
|
||||
|
||||
def _decrypt(self, cipher):
|
||||
return self.key._decrypt(cipher[0])
|
||||
|
||||
def _sign(self, M, K):
|
||||
return (self.key._sign(M),)
|
||||
|
||||
def _verify(self, M, sig):
|
||||
return self.key._verify(M, sig[0])
|
||||
|
||||
def _blind(self, M, B):
|
||||
return self.key._blind(M, B)
|
||||
|
||||
def _unblind(self, M, B):
|
||||
return self.key._unblind(M, B)
|
||||
|
||||
def can_blind (self):
|
||||
return 1
|
||||
|
||||
def size(self):
|
||||
return self.key.size()
|
||||
|
||||
def has_private(self):
|
||||
return self.key.has_private()
|
||||
|
||||
def publickey(self):
|
||||
return construct_c((self.key.n, self.key.e))
|
||||
|
||||
def generate_c(bits, randfunc, progress_func = None):
|
||||
# Generate the prime factors of n
|
||||
if progress_func:
|
||||
progress_func('p,q\n')
|
||||
|
||||
p = q = 1L
|
||||
while number.size(p*q) < bits:
|
||||
p = pubkey.getPrime(bits/2, randfunc)
|
||||
q = pubkey.getPrime(bits/2, randfunc)
|
||||
|
||||
# p shall be smaller than q (for calc of u)
|
||||
if p > q:
|
||||
(p, q)=(q, p)
|
||||
if progress_func:
|
||||
progress_func('u\n')
|
||||
u=pubkey.inverse(p, q)
|
||||
n=p*q
|
||||
|
||||
e = 65537L
|
||||
if progress_func:
|
||||
progress_func('d\n')
|
||||
d=pubkey.inverse(e, (p-1)*(q-1))
|
||||
key = _fastmath.rsa_construct(n,e,d,p,q,u)
|
||||
obj = RSAobj_c(key)
|
||||
|
||||
## print p
|
||||
## print q
|
||||
## print number.size(p), number.size(q), number.size(q*p),
|
||||
## print obj.size(), bits
|
||||
assert bits <= 1+obj.size(), "Generated key is too small"
|
||||
return obj
|
||||
|
||||
|
||||
def construct_c(tuple):
|
||||
key = apply(_fastmath.rsa_construct, tuple)
|
||||
return RSAobj_c(key)
|
||||
|
||||
object = RSAobj
|
||||
|
||||
generate_py = generate
|
||||
construct_py = construct
|
||||
|
||||
if _fastmath:
|
||||
#print "using C version of RSA"
|
||||
generate = generate_c
|
||||
construct = construct_c
|
||||
error = _fastmath.error
|
@ -1,17 +0,0 @@
|
||||
"""Public-key encryption and signature algorithms.
|
||||
|
||||
Public-key encryption uses two different keys, one for encryption and
|
||||
one for decryption. The encryption key can be made public, and the
|
||||
decryption key is kept private. Many public-key algorithms can also
|
||||
be used to sign messages, and some can *only* be used for signatures.
|
||||
|
||||
Crypto.PublicKey.DSA Digital Signature Algorithm. (Signature only)
|
||||
Crypto.PublicKey.ElGamal (Signing and encryption)
|
||||
Crypto.PublicKey.RSA (Signing, encryption, and blinding)
|
||||
Crypto.PublicKey.qNEW (Signature only)
|
||||
|
||||
"""
|
||||
|
||||
__all__ = ['RSA', 'DSA', 'ElGamal', 'qNEW']
|
||||
__revision__ = "$Id: __init__.py,v 1.4 2003/04/03 20:27:13 akuchling Exp $"
|
||||
|
@ -1,172 +0,0 @@
|
||||
#
|
||||
# pubkey.py : Internal functions for public key operations
|
||||
#
|
||||
# Part of the Python Cryptography Toolkit
|
||||
#
|
||||
# Distribute and use freely; there are no restrictions on further
|
||||
# dissemination and usage except those imposed by the laws of your
|
||||
# country of residence. This software is provided "as is" without
|
||||
# warranty of fitness for use or suitability for any purpose, express
|
||||
# or implied. Use at your own risk or not at all.
|
||||
#
|
||||
|
||||
__revision__ = "$Id: pubkey.py,v 1.11 2003/04/03 20:36:14 akuchling Exp $"
|
||||
|
||||
import types, warnings
|
||||
from allmydata.Crypto.Util.number import *
|
||||
|
||||
# Basic public key class
|
||||
class pubkey:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def __getstate__(self):
|
||||
"""To keep key objects platform-independent, the key data is
|
||||
converted to standard Python long integers before being
|
||||
written out. It will then be reconverted as necessary on
|
||||
restoration."""
|
||||
d=self.__dict__
|
||||
for key in self.keydata:
|
||||
if d.has_key(key): d[key]=long(d[key])
|
||||
return d
|
||||
|
||||
def __setstate__(self, d):
|
||||
"""On unpickling a key object, the key data is converted to the big
|
||||
number representation being used, whether that is Python long
|
||||
integers, MPZ objects, or whatever."""
|
||||
for key in self.keydata:
|
||||
if d.has_key(key): self.__dict__[key]=bignum(d[key])
|
||||
|
||||
def encrypt(self, plaintext, K):
|
||||
"""encrypt(plaintext:string|long, K:string|long) : tuple
|
||||
Encrypt the string or integer plaintext. K is a random
|
||||
parameter required by some algorithms.
|
||||
"""
|
||||
wasString=0
|
||||
if isinstance(plaintext, types.StringType):
|
||||
plaintext=bytes_to_long(plaintext) ; wasString=1
|
||||
if isinstance(K, types.StringType):
|
||||
K=bytes_to_long(K)
|
||||
ciphertext=self._encrypt(plaintext, K)
|
||||
if wasString: return tuple(map(long_to_bytes, ciphertext))
|
||||
else: return ciphertext
|
||||
|
||||
def decrypt(self, ciphertext):
|
||||
"""decrypt(ciphertext:tuple|string|long): string
|
||||
Decrypt 'ciphertext' using this key.
|
||||
"""
|
||||
wasString=0
|
||||
if not isinstance(ciphertext, types.TupleType):
|
||||
ciphertext=(ciphertext,)
|
||||
if isinstance(ciphertext[0], types.StringType):
|
||||
ciphertext=tuple(map(bytes_to_long, ciphertext)) ; wasString=1
|
||||
plaintext=self._decrypt(ciphertext)
|
||||
if wasString: return long_to_bytes(plaintext)
|
||||
else: return plaintext
|
||||
|
||||
def sign(self, M, K):
|
||||
"""sign(M : string|long, K:string|long) : tuple
|
||||
Return a tuple containing the signature for the message M.
|
||||
K is a random parameter required by some algorithms.
|
||||
"""
|
||||
if (not self.has_private()):
|
||||
raise error, 'Private key not available in this object'
|
||||
if isinstance(M, types.StringType): M=bytes_to_long(M)
|
||||
if isinstance(K, types.StringType): K=bytes_to_long(K)
|
||||
return self._sign(M, K)
|
||||
|
||||
def verify (self, M, signature):
|
||||
"""verify(M:string|long, signature:tuple) : bool
|
||||
Verify that the signature is valid for the message M;
|
||||
returns true if the signature checks out.
|
||||
"""
|
||||
if isinstance(M, types.StringType): M=bytes_to_long(M)
|
||||
return self._verify(M, signature)
|
||||
|
||||
# alias to compensate for the old validate() name
|
||||
def validate (self, M, signature):
|
||||
warnings.warn("validate() method name is obsolete; use verify()",
|
||||
DeprecationWarning)
|
||||
|
||||
def blind(self, M, B):
|
||||
"""blind(M : string|long, B : string|long) : string|long
|
||||
Blind message M using blinding factor B.
|
||||
"""
|
||||
wasString=0
|
||||
if isinstance(M, types.StringType):
|
||||
M=bytes_to_long(M) ; wasString=1
|
||||
if isinstance(B, types.StringType): B=bytes_to_long(B)
|
||||
blindedmessage=self._blind(M, B)
|
||||
if wasString: return long_to_bytes(blindedmessage)
|
||||
else: return blindedmessage
|
||||
|
||||
def unblind(self, M, B):
|
||||
"""unblind(M : string|long, B : string|long) : string|long
|
||||
Unblind message M using blinding factor B.
|
||||
"""
|
||||
wasString=0
|
||||
if isinstance(M, types.StringType):
|
||||
M=bytes_to_long(M) ; wasString=1
|
||||
if isinstance(B, types.StringType): B=bytes_to_long(B)
|
||||
unblindedmessage=self._unblind(M, B)
|
||||
if wasString: return long_to_bytes(unblindedmessage)
|
||||
else: return unblindedmessage
|
||||
|
||||
|
||||
# The following methods will usually be left alone, except for
|
||||
# signature-only algorithms. They both return Boolean values
|
||||
# recording whether this key's algorithm can sign and encrypt.
|
||||
def can_sign (self):
|
||||
"""can_sign() : bool
|
||||
Return a Boolean value recording whether this algorithm can
|
||||
generate signatures. (This does not imply that this
|
||||
particular key object has the private information required to
|
||||
to generate a signature.)
|
||||
"""
|
||||
return 1
|
||||
|
||||
def can_encrypt (self):
|
||||
"""can_encrypt() : bool
|
||||
Return a Boolean value recording whether this algorithm can
|
||||
encrypt data. (This does not imply that this
|
||||
particular key object has the private information required to
|
||||
to decrypt a message.)
|
||||
"""
|
||||
return 1
|
||||
|
||||
def can_blind (self):
|
||||
"""can_blind() : bool
|
||||
Return a Boolean value recording whether this algorithm can
|
||||
blind data. (This does not imply that this
|
||||
particular key object has the private information required to
|
||||
to blind a message.)
|
||||
"""
|
||||
return 0
|
||||
|
||||
# The following methods will certainly be overridden by
|
||||
# subclasses.
|
||||
|
||||
def size (self):
|
||||
"""size() : int
|
||||
Return the maximum number of bits that can be handled by this key.
|
||||
"""
|
||||
return 0
|
||||
|
||||
def has_private (self):
|
||||
"""has_private() : bool
|
||||
Return a Boolean denoting whether the object contains
|
||||
private components.
|
||||
"""
|
||||
return 0
|
||||
|
||||
def publickey (self):
|
||||
"""publickey(): object
|
||||
Return a new key object containing only the public information.
|
||||
"""
|
||||
return self
|
||||
|
||||
def __eq__ (self, other):
|
||||
"""__eq__(other): 0, 1
|
||||
Compare us to other for equality.
|
||||
"""
|
||||
return self.__getstate__() == other.__getstate__()
|
@ -1,170 +0,0 @@
|
||||
#
|
||||
# qNEW.py : The q-NEW signature algorithm.
|
||||
#
|
||||
# Part of the Python Cryptography Toolkit
|
||||
#
|
||||
# Distribute and use freely; there are no restrictions on further
|
||||
# dissemination and usage except those imposed by the laws of your
|
||||
# country of residence. This software is provided "as is" without
|
||||
# warranty of fitness for use or suitability for any purpose, express
|
||||
# or implied. Use at your own risk or not at all.
|
||||
#
|
||||
|
||||
__revision__ = "$Id: qNEW.py,v 1.8 2003/04/04 15:13:35 akuchling Exp $"
|
||||
|
||||
from allmydata.Crypto.PublicKey import pubkey
|
||||
from allmydata.Crypto.Util.number import *
|
||||
from allmydata.Crypto.Hash import SHA
|
||||
|
||||
class error (Exception):
|
||||
pass
|
||||
|
||||
HASHBITS = 160 # Size of SHA digests
|
||||
|
||||
def generate(bits, randfunc, progress_func=None):
|
||||
"""generate(bits:int, randfunc:callable, progress_func:callable)
|
||||
|
||||
Generate a qNEW key of length 'bits', using 'randfunc' to get
|
||||
random data and 'progress_func', if present, to display
|
||||
the progress of the key generation.
|
||||
"""
|
||||
obj=qNEWobj()
|
||||
|
||||
# Generate prime numbers p and q. q is a 160-bit prime
|
||||
# number. p is another prime number (the modulus) whose bit
|
||||
# size is chosen by the caller, and is generated so that p-1
|
||||
# is a multiple of q.
|
||||
#
|
||||
# Note that only a single seed is used to
|
||||
# generate p and q; if someone generates a key for you, you can
|
||||
# use the seed to duplicate the key generation. This can
|
||||
# protect you from someone generating values of p,q that have
|
||||
# some special form that's easy to break.
|
||||
if progress_func:
|
||||
progress_func('p,q\n')
|
||||
while (1):
|
||||
obj.q = getPrime(160, randfunc)
|
||||
# assert pow(2, 159L)<obj.q<pow(2, 160L)
|
||||
obj.seed = S = long_to_bytes(obj.q)
|
||||
C, N, V = 0, 2, {}
|
||||
# Compute b and n such that bits-1 = b + n*HASHBITS
|
||||
n= (bits-1) / HASHBITS
|
||||
b= (bits-1) % HASHBITS ; powb=2L << b
|
||||
powL1=pow(long(2), bits-1)
|
||||
while C<4096:
|
||||
# The V array will contain (bits-1) bits of random
|
||||
# data, that are assembled to produce a candidate
|
||||
# value for p.
|
||||
for k in range(0, n+1):
|
||||
V[k]=bytes_to_long(SHA.new(S+str(N)+str(k)).digest())
|
||||
p = V[n] % powb
|
||||
for k in range(n-1, -1, -1):
|
||||
p= (p << long(HASHBITS) )+V[k]
|
||||
p = p+powL1 # Ensure the high bit is set
|
||||
|
||||
# Ensure that p-1 is a multiple of q
|
||||
p = p - (p % (2*obj.q)-1)
|
||||
|
||||
# If p is still the right size, and it's prime, we're done!
|
||||
if powL1<=p and isPrime(p):
|
||||
break
|
||||
|
||||
# Otherwise, increment the counter and try again
|
||||
C, N = C+1, N+n+1
|
||||
if C<4096:
|
||||
break # Ended early, so exit the while loop
|
||||
if progress_func:
|
||||
progress_func('4096 values of p tried\n')
|
||||
|
||||
obj.p = p
|
||||
power=(p-1)/obj.q
|
||||
|
||||
# Next parameter: g = h**((p-1)/q) mod p, such that h is any
|
||||
# number <p-1, and g>1. g is kept; h can be discarded.
|
||||
if progress_func:
|
||||
progress_func('h,g\n')
|
||||
while (1):
|
||||
h=bytes_to_long(randfunc(bits)) % (p-1)
|
||||
g=pow(h, power, p)
|
||||
if 1<h<p-1 and g>1:
|
||||
break
|
||||
obj.g=g
|
||||
|
||||
# x is the private key information, and is
|
||||
# just a random number between 0 and q.
|
||||
# y=g**x mod p, and is part of the public information.
|
||||
if progress_func:
|
||||
progress_func('x,y\n')
|
||||
while (1):
|
||||
x=bytes_to_long(randfunc(20))
|
||||
if 0 < x < obj.q:
|
||||
break
|
||||
obj.x, obj.y=x, pow(g, x, p)
|
||||
|
||||
return obj
|
||||
|
||||
# Construct a qNEW object
|
||||
def construct(tuple):
|
||||
"""construct(tuple:(long,long,long,long)|(long,long,long,long,long)
|
||||
Construct a qNEW object from a 4- or 5-tuple of numbers.
|
||||
"""
|
||||
obj=qNEWobj()
|
||||
if len(tuple) not in [4,5]:
|
||||
raise error, 'argument for construct() wrong length'
|
||||
for i in range(len(tuple)):
|
||||
field = obj.keydata[i]
|
||||
setattr(obj, field, tuple[i])
|
||||
return obj
|
||||
|
||||
class qNEWobj(pubkey.pubkey):
|
||||
keydata=['p', 'q', 'g', 'y', 'x']
|
||||
|
||||
def _sign(self, M, K=''):
|
||||
if (self.q<=K):
|
||||
raise error, 'K is greater than q'
|
||||
if M<0:
|
||||
raise error, 'Illegal value of M (<0)'
|
||||
if M>=pow(2,161L):
|
||||
raise error, 'Illegal value of M (too large)'
|
||||
r=pow(self.g, K, self.p) % self.q
|
||||
s=(K- (r*M*self.x % self.q)) % self.q
|
||||
return (r,s)
|
||||
def _verify(self, M, sig):
|
||||
r, s = sig
|
||||
if r<=0 or r>=self.q or s<=0 or s>=self.q:
|
||||
return 0
|
||||
if M<0:
|
||||
raise error, 'Illegal value of M (<0)'
|
||||
if M<=0 or M>=pow(2,161L):
|
||||
return 0
|
||||
v1 = pow(self.g, s, self.p)
|
||||
v2 = pow(self.y, M*r, self.p)
|
||||
v = ((v1*v2) % self.p)
|
||||
v = v % self.q
|
||||
if v==r:
|
||||
return 1
|
||||
return 0
|
||||
|
||||
def size(self):
|
||||
"Return the maximum number of bits that can be handled by this key."
|
||||
return 160
|
||||
|
||||
def has_private(self):
|
||||
"""Return a Boolean denoting whether the object contains
|
||||
private components."""
|
||||
return hasattr(self, 'x')
|
||||
|
||||
def can_sign(self):
|
||||
"""Return a Boolean value recording whether this algorithm can generate signatures."""
|
||||
return 1
|
||||
|
||||
def can_encrypt(self):
|
||||
"""Return a Boolean value recording whether this algorithm can encrypt data."""
|
||||
return 0
|
||||
|
||||
def publickey(self):
|
||||
"""Return a new key object containing only the public information."""
|
||||
return construct((self.p, self.q, self.g, self.y))
|
||||
|
||||
object = qNEWobj
|
||||
|
@ -1,48 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Script to time fast and slow RSA operations
|
||||
# Contributed by Joris Bontje.
|
||||
|
||||
import time, pprint
|
||||
from allmydata.Crypto.PublicKey import *
|
||||
from allmydata.Crypto.Util.randpool import RandomPool
|
||||
from allmydata.Crypto.Util import number
|
||||
|
||||
pool = RandomPool()
|
||||
pool.stir()
|
||||
|
||||
KEYSIZE=2048
|
||||
COUNT=5
|
||||
fasttime=0
|
||||
slowtime=0
|
||||
for x in range(COUNT):
|
||||
begintime=time.time()
|
||||
rsa=RSA.generate(KEYSIZE, pool.get_bytes)
|
||||
endtime=time.time()
|
||||
print "Server: Generating %d bit RSA key: %f s" % (KEYSIZE, endtime-begintime)
|
||||
rsa_slow=RSA.construct((rsa.n,rsa.e,rsa.d))
|
||||
|
||||
code=number.getRandomNumber(256, pool.get_bytes)
|
||||
begintime=time.time()
|
||||
signature=rsa.sign(code,None)[0]
|
||||
endtime=time.time()
|
||||
fast=(endtime-begintime)
|
||||
fasttime=fasttime+fast
|
||||
print "Fast signing took %f s" % fast
|
||||
|
||||
begintime=time.time()
|
||||
signature_slow=rsa_slow.sign(code,None)[0]
|
||||
endtime=time.time()
|
||||
slow=(endtime-begintime)
|
||||
slowtime=slowtime+slow
|
||||
print "Slow signing took %f s" % slow
|
||||
|
||||
if rsa.verify(code,(signature,)) and signature==signature_slow:
|
||||
print "Signature okay"
|
||||
else:
|
||||
print "Signature WRONG"
|
||||
|
||||
print "faster: %f" % (slow/fast)
|
||||
|
||||
print "Based on %d signatures with %d bits keys the optimized\n RSA decryption/signing algorithm is %f times faster" % (COUNT, KEYSIZE, (slowtime/fasttime))
|
||||
|
@ -1,31 +0,0 @@
|
||||
|
||||
* Add more tests for random pool code?
|
||||
|
||||
* Manual and Web page: point to SF project for bug reports
|
||||
|
||||
* Update documentation (mention dodgy status of PublicKey code)
|
||||
|
||||
* Clean up markup in pycrypt.tex
|
||||
|
||||
* Reformat all the code to MEMS Exchange style
|
||||
|
||||
* Document the functions and macros for adding a new algorithm
|
||||
Hash functions:
|
||||
hash_init(), hash_copy(), DIGEST_SIZE, hash_update(), hash_digest()
|
||||
Block functions:
|
||||
...
|
||||
|
||||
* Provide drop-in support for extensions/drivers like
|
||||
amkCrypto/mxCrypto. There should be some way to register these
|
||||
drivers in your package, e.g. by defining a certain subdirectory
|
||||
to be a place where pycrypto looks for these drivers at startup
|
||||
time.
|
||||
|
||||
* Add a secure PRNG (Yarrow, maybe?)
|
||||
|
||||
* A secret sharing module should be added to Util or Protocols.
|
||||
|
||||
Documentation:
|
||||
Document chaff/winnow better
|
||||
Add docstrings everywhere.
|
||||
|
@ -1,342 +0,0 @@
|
||||
#!/usr/local/bin/python
|
||||
# rfc1751.py : Converts between 128-bit strings and a human-readable
|
||||
# sequence of words, as defined in RFC1751: "A Convention for
|
||||
# Human-Readable 128-bit Keys", by Daniel L. McDonald.
|
||||
|
||||
__revision__ = "$Id: RFC1751.py,v 1.6 2003/04/04 15:15:10 akuchling Exp $"
|
||||
|
||||
|
||||
import string, binascii
|
||||
|
||||
binary={0:'0000', 1:'0001', 2:'0010', 3:'0011', 4:'0100', 5:'0101',
|
||||
6:'0110', 7:'0111', 8:'1000', 9:'1001', 10:'1010', 11:'1011',
|
||||
12:'1100', 13:'1101', 14:'1110', 15:'1111'}
|
||||
|
||||
def _key2bin(s):
|
||||
"Convert a key into a string of binary digits"
|
||||
kl=map(lambda x: ord(x), s)
|
||||
kl=map(lambda x: binary[x/16]+binary[x&15], kl)
|
||||
return ''.join(kl)
|
||||
|
||||
def _extract(key, start, length):
|
||||
"""Extract a bitstring from a string of binary digits, and return its
|
||||
numeric value."""
|
||||
k=key[start:start+length]
|
||||
return reduce(lambda x,y: x*2+ord(y)-48, k, 0)
|
||||
|
||||
def key_to_english (key):
|
||||
"""key_to_english(key:string) : string
|
||||
Transform an arbitrary key into a string containing English words.
|
||||
The key length must be a multiple of 8.
|
||||
"""
|
||||
english=''
|
||||
for index in range(0, len(key), 8): # Loop over 8-byte subkeys
|
||||
subkey=key[index:index+8]
|
||||
# Compute the parity of the key
|
||||
skbin=_key2bin(subkey) ; p=0
|
||||
for i in range(0, 64, 2): p=p+_extract(skbin, i, 2)
|
||||
# Append parity bits to the subkey
|
||||
skbin=_key2bin(subkey+chr((p<<6) & 255))
|
||||
for i in range(0, 64, 11):
|
||||
english=english+wordlist[_extract(skbin, i, 11)]+' '
|
||||
|
||||
return english[:-1] # Remove the trailing space
|
||||
|
||||
def english_to_key (str):
|
||||
"""english_to_key(string):string
|
||||
Transform a string into a corresponding key.
|
||||
The string must contain words separated by whitespace; the number
|
||||
of words must be a multiple of 6.
|
||||
"""
|
||||
|
||||
L=string.split(string.upper(str)) ; key=''
|
||||
for index in range(0, len(L), 6):
|
||||
sublist=L[index:index+6] ; char=9*[0] ; bits=0
|
||||
for i in sublist:
|
||||
index = wordlist.index(i)
|
||||
shift = (8-(bits+11)%8) %8
|
||||
y = index << shift
|
||||
cl, cc, cr = (y>>16), (y>>8)&0xff, y & 0xff
|
||||
if (shift>5):
|
||||
char[bits/8] = char[bits/8] | cl
|
||||
char[bits/8+1] = char[bits/8+1] | cc
|
||||
char[bits/8+2] = char[bits/8+2] | cr
|
||||
elif shift>-3:
|
||||
char[bits/8] = char[bits/8] | cc
|
||||
char[bits/8+1] = char[bits/8+1] | cr
|
||||
else: char[bits/8] = char[bits/8] | cr
|
||||
bits=bits+11
|
||||
subkey=reduce(lambda x,y:x+chr(y), char, '')
|
||||
|
||||
# Check the parity of the resulting key
|
||||
skbin=_key2bin(subkey)
|
||||
p=0
|
||||
for i in range(0, 64, 2): p=p+_extract(skbin, i, 2)
|
||||
if (p&3) != _extract(skbin, 64, 2):
|
||||
raise ValueError, "Parity error in resulting key"
|
||||
key=key+subkey[0:8]
|
||||
return key
|
||||
|
||||
wordlist=[ "A", "ABE", "ACE", "ACT", "AD", "ADA", "ADD",
|
||||
"AGO", "AID", "AIM", "AIR", "ALL", "ALP", "AM", "AMY", "AN", "ANA",
|
||||
"AND", "ANN", "ANT", "ANY", "APE", "APS", "APT", "ARC", "ARE", "ARK",
|
||||
"ARM", "ART", "AS", "ASH", "ASK", "AT", "ATE", "AUG", "AUK", "AVE",
|
||||
"AWE", "AWK", "AWL", "AWN", "AX", "AYE", "BAD", "BAG", "BAH", "BAM",
|
||||
"BAN", "BAR", "BAT", "BAY", "BE", "BED", "BEE", "BEG", "BEN", "BET",
|
||||
"BEY", "BIB", "BID", "BIG", "BIN", "BIT", "BOB", "BOG", "BON", "BOO",
|
||||
"BOP", "BOW", "BOY", "BUB", "BUD", "BUG", "BUM", "BUN", "BUS", "BUT",
|
||||
"BUY", "BY", "BYE", "CAB", "CAL", "CAM", "CAN", "CAP", "CAR", "CAT",
|
||||
"CAW", "COD", "COG", "COL", "CON", "COO", "COP", "COT", "COW", "COY",
|
||||
"CRY", "CUB", "CUE", "CUP", "CUR", "CUT", "DAB", "DAD", "DAM", "DAN",
|
||||
"DAR", "DAY", "DEE", "DEL", "DEN", "DES", "DEW", "DID", "DIE", "DIG",
|
||||
"DIN", "DIP", "DO", "DOE", "DOG", "DON", "DOT", "DOW", "DRY", "DUB",
|
||||
"DUD", "DUE", "DUG", "DUN", "EAR", "EAT", "ED", "EEL", "EGG", "EGO",
|
||||
"ELI", "ELK", "ELM", "ELY", "EM", "END", "EST", "ETC", "EVA", "EVE",
|
||||
"EWE", "EYE", "FAD", "FAN", "FAR", "FAT", "FAY", "FED", "FEE", "FEW",
|
||||
"FIB", "FIG", "FIN", "FIR", "FIT", "FLO", "FLY", "FOE", "FOG", "FOR",
|
||||
"FRY", "FUM", "FUN", "FUR", "GAB", "GAD", "GAG", "GAL", "GAM", "GAP",
|
||||
"GAS", "GAY", "GEE", "GEL", "GEM", "GET", "GIG", "GIL", "GIN", "GO",
|
||||
"GOT", "GUM", "GUN", "GUS", "GUT", "GUY", "GYM", "GYP", "HA", "HAD",
|
||||
"HAL", "HAM", "HAN", "HAP", "HAS", "HAT", "HAW", "HAY", "HE", "HEM",
|
||||
"HEN", "HER", "HEW", "HEY", "HI", "HID", "HIM", "HIP", "HIS", "HIT",
|
||||
"HO", "HOB", "HOC", "HOE", "HOG", "HOP", "HOT", "HOW", "HUB", "HUE",
|
||||
"HUG", "HUH", "HUM", "HUT", "I", "ICY", "IDA", "IF", "IKE", "ILL",
|
||||
"INK", "INN", "IO", "ION", "IQ", "IRA", "IRE", "IRK", "IS", "IT",
|
||||
"ITS", "IVY", "JAB", "JAG", "JAM", "JAN", "JAR", "JAW", "JAY", "JET",
|
||||
"JIG", "JIM", "JO", "JOB", "JOE", "JOG", "JOT", "JOY", "JUG", "JUT",
|
||||
"KAY", "KEG", "KEN", "KEY", "KID", "KIM", "KIN", "KIT", "LA", "LAB",
|
||||
"LAC", "LAD", "LAG", "LAM", "LAP", "LAW", "LAY", "LEA", "LED", "LEE",
|
||||
"LEG", "LEN", "LEO", "LET", "LEW", "LID", "LIE", "LIN", "LIP", "LIT",
|
||||
"LO", "LOB", "LOG", "LOP", "LOS", "LOT", "LOU", "LOW", "LOY", "LUG",
|
||||
"LYE", "MA", "MAC", "MAD", "MAE", "MAN", "MAO", "MAP", "MAT", "MAW",
|
||||
"MAY", "ME", "MEG", "MEL", "MEN", "MET", "MEW", "MID", "MIN", "MIT",
|
||||
"MOB", "MOD", "MOE", "MOO", "MOP", "MOS", "MOT", "MOW", "MUD", "MUG",
|
||||
"MUM", "MY", "NAB", "NAG", "NAN", "NAP", "NAT", "NAY", "NE", "NED",
|
||||
"NEE", "NET", "NEW", "NIB", "NIL", "NIP", "NIT", "NO", "NOB", "NOD",
|
||||
"NON", "NOR", "NOT", "NOV", "NOW", "NU", "NUN", "NUT", "O", "OAF",
|
||||
"OAK", "OAR", "OAT", "ODD", "ODE", "OF", "OFF", "OFT", "OH", "OIL",
|
||||
"OK", "OLD", "ON", "ONE", "OR", "ORB", "ORE", "ORR", "OS", "OTT",
|
||||
"OUR", "OUT", "OVA", "OW", "OWE", "OWL", "OWN", "OX", "PA", "PAD",
|
||||
"PAL", "PAM", "PAN", "PAP", "PAR", "PAT", "PAW", "PAY", "PEA", "PEG",
|
||||
"PEN", "PEP", "PER", "PET", "PEW", "PHI", "PI", "PIE", "PIN", "PIT",
|
||||
"PLY", "PO", "POD", "POE", "POP", "POT", "POW", "PRO", "PRY", "PUB",
|
||||
"PUG", "PUN", "PUP", "PUT", "QUO", "RAG", "RAM", "RAN", "RAP", "RAT",
|
||||
"RAW", "RAY", "REB", "RED", "REP", "RET", "RIB", "RID", "RIG", "RIM",
|
||||
"RIO", "RIP", "ROB", "ROD", "ROE", "RON", "ROT", "ROW", "ROY", "RUB",
|
||||
"RUE", "RUG", "RUM", "RUN", "RYE", "SAC", "SAD", "SAG", "SAL", "SAM",
|
||||
"SAN", "SAP", "SAT", "SAW", "SAY", "SEA", "SEC", "SEE", "SEN", "SET",
|
||||
"SEW", "SHE", "SHY", "SIN", "SIP", "SIR", "SIS", "SIT", "SKI", "SKY",
|
||||
"SLY", "SO", "SOB", "SOD", "SON", "SOP", "SOW", "SOY", "SPA", "SPY",
|
||||
"SUB", "SUD", "SUE", "SUM", "SUN", "SUP", "TAB", "TAD", "TAG", "TAN",
|
||||
"TAP", "TAR", "TEA", "TED", "TEE", "TEN", "THE", "THY", "TIC", "TIE",
|
||||
"TIM", "TIN", "TIP", "TO", "TOE", "TOG", "TOM", "TON", "TOO", "TOP",
|
||||
"TOW", "TOY", "TRY", "TUB", "TUG", "TUM", "TUN", "TWO", "UN", "UP",
|
||||
"US", "USE", "VAN", "VAT", "VET", "VIE", "WAD", "WAG", "WAR", "WAS",
|
||||
"WAY", "WE", "WEB", "WED", "WEE", "WET", "WHO", "WHY", "WIN", "WIT",
|
||||
"WOK", "WON", "WOO", "WOW", "WRY", "WU", "YAM", "YAP", "YAW", "YE",
|
||||
"YEA", "YES", "YET", "YOU", "ABED", "ABEL", "ABET", "ABLE", "ABUT",
|
||||
"ACHE", "ACID", "ACME", "ACRE", "ACTA", "ACTS", "ADAM", "ADDS",
|
||||
"ADEN", "AFAR", "AFRO", "AGEE", "AHEM", "AHOY", "AIDA", "AIDE",
|
||||
"AIDS", "AIRY", "AJAR", "AKIN", "ALAN", "ALEC", "ALGA", "ALIA",
|
||||
"ALLY", "ALMA", "ALOE", "ALSO", "ALTO", "ALUM", "ALVA", "AMEN",
|
||||
"AMES", "AMID", "AMMO", "AMOK", "AMOS", "AMRA", "ANDY", "ANEW",
|
||||
"ANNA", "ANNE", "ANTE", "ANTI", "AQUA", "ARAB", "ARCH", "AREA",
|
||||
"ARGO", "ARID", "ARMY", "ARTS", "ARTY", "ASIA", "ASKS", "ATOM",
|
||||
"AUNT", "AURA", "AUTO", "AVER", "AVID", "AVIS", "AVON", "AVOW",
|
||||
"AWAY", "AWRY", "BABE", "BABY", "BACH", "BACK", "BADE", "BAIL",
|
||||
"BAIT", "BAKE", "BALD", "BALE", "BALI", "BALK", "BALL", "BALM",
|
||||
"BAND", "BANE", "BANG", "BANK", "BARB", "BARD", "BARE", "BARK",
|
||||
"BARN", "BARR", "BASE", "BASH", "BASK", "BASS", "BATE", "BATH",
|
||||
"BAWD", "BAWL", "BEAD", "BEAK", "BEAM", "BEAN", "BEAR", "BEAT",
|
||||
"BEAU", "BECK", "BEEF", "BEEN", "BEER",
|
||||
"BEET", "BELA", "BELL", "BELT", "BEND", "BENT", "BERG", "BERN",
|
||||
"BERT", "BESS", "BEST", "BETA", "BETH", "BHOY", "BIAS", "BIDE",
|
||||
"BIEN", "BILE", "BILK", "BILL", "BIND", "BING", "BIRD", "BITE",
|
||||
"BITS", "BLAB", "BLAT", "BLED", "BLEW", "BLOB", "BLOC", "BLOT",
|
||||
"BLOW", "BLUE", "BLUM", "BLUR", "BOAR", "BOAT", "BOCA", "BOCK",
|
||||
"BODE", "BODY", "BOGY", "BOHR", "BOIL", "BOLD", "BOLO", "BOLT",
|
||||
"BOMB", "BONA", "BOND", "BONE", "BONG", "BONN", "BONY", "BOOK",
|
||||
"BOOM", "BOON", "BOOT", "BORE", "BORG", "BORN", "BOSE", "BOSS",
|
||||
"BOTH", "BOUT", "BOWL", "BOYD", "BRAD", "BRAE", "BRAG", "BRAN",
|
||||
"BRAY", "BRED", "BREW", "BRIG", "BRIM", "BROW", "BUCK", "BUDD",
|
||||
"BUFF", "BULB", "BULK", "BULL", "BUNK", "BUNT", "BUOY", "BURG",
|
||||
"BURL", "BURN", "BURR", "BURT", "BURY", "BUSH", "BUSS", "BUST",
|
||||
"BUSY", "BYTE", "CADY", "CAFE", "CAGE", "CAIN", "CAKE", "CALF",
|
||||
"CALL", "CALM", "CAME", "CANE", "CANT", "CARD", "CARE", "CARL",
|
||||
"CARR", "CART", "CASE", "CASH", "CASK", "CAST", "CAVE", "CEIL",
|
||||
"CELL", "CENT", "CERN", "CHAD", "CHAR", "CHAT", "CHAW", "CHEF",
|
||||
"CHEN", "CHEW", "CHIC", "CHIN", "CHOU", "CHOW", "CHUB", "CHUG",
|
||||
"CHUM", "CITE", "CITY", "CLAD", "CLAM", "CLAN", "CLAW", "CLAY",
|
||||
"CLOD", "CLOG", "CLOT", "CLUB", "CLUE", "COAL", "COAT", "COCA",
|
||||
"COCK", "COCO", "CODA", "CODE", "CODY", "COED", "COIL", "COIN",
|
||||
"COKE", "COLA", "COLD", "COLT", "COMA", "COMB", "COME", "COOK",
|
||||
"COOL", "COON", "COOT", "CORD", "CORE", "CORK", "CORN", "COST",
|
||||
"COVE", "COWL", "CRAB", "CRAG", "CRAM", "CRAY", "CREW", "CRIB",
|
||||
"CROW", "CRUD", "CUBA", "CUBE", "CUFF", "CULL", "CULT", "CUNY",
|
||||
"CURB", "CURD", "CURE", "CURL", "CURT", "CUTS", "DADE", "DALE",
|
||||
"DAME", "DANA", "DANE", "DANG", "DANK", "DARE", "DARK", "DARN",
|
||||
"DART", "DASH", "DATA", "DATE", "DAVE", "DAVY", "DAWN", "DAYS",
|
||||
"DEAD", "DEAF", "DEAL", "DEAN", "DEAR", "DEBT", "DECK", "DEED",
|
||||
"DEEM", "DEER", "DEFT", "DEFY", "DELL", "DENT", "DENY", "DESK",
|
||||
"DIAL", "DICE", "DIED", "DIET", "DIME", "DINE", "DING", "DINT",
|
||||
"DIRE", "DIRT", "DISC", "DISH", "DISK", "DIVE", "DOCK", "DOES",
|
||||
"DOLE", "DOLL", "DOLT", "DOME", "DONE", "DOOM", "DOOR", "DORA",
|
||||
"DOSE", "DOTE", "DOUG", "DOUR", "DOVE", "DOWN", "DRAB", "DRAG",
|
||||
"DRAM", "DRAW", "DREW", "DRUB", "DRUG", "DRUM", "DUAL", "DUCK",
|
||||
"DUCT", "DUEL", "DUET", "DUKE", "DULL", "DUMB", "DUNE", "DUNK",
|
||||
"DUSK", "DUST", "DUTY", "EACH", "EARL", "EARN", "EASE", "EAST",
|
||||
"EASY", "EBEN", "ECHO", "EDDY", "EDEN", "EDGE", "EDGY", "EDIT",
|
||||
"EDNA", "EGAN", "ELAN", "ELBA", "ELLA", "ELSE", "EMIL", "EMIT",
|
||||
"EMMA", "ENDS", "ERIC", "EROS", "EVEN", "EVER", "EVIL", "EYED",
|
||||
"FACE", "FACT", "FADE", "FAIL", "FAIN", "FAIR", "FAKE", "FALL",
|
||||
"FAME", "FANG", "FARM", "FAST", "FATE", "FAWN", "FEAR", "FEAT",
|
||||
"FEED", "FEEL", "FEET", "FELL", "FELT", "FEND", "FERN", "FEST",
|
||||
"FEUD", "FIEF", "FIGS", "FILE", "FILL", "FILM", "FIND", "FINE",
|
||||
"FINK", "FIRE", "FIRM", "FISH", "FISK", "FIST", "FITS", "FIVE",
|
||||
"FLAG", "FLAK", "FLAM", "FLAT", "FLAW", "FLEA", "FLED", "FLEW",
|
||||
"FLIT", "FLOC", "FLOG", "FLOW", "FLUB", "FLUE", "FOAL", "FOAM",
|
||||
"FOGY", "FOIL", "FOLD", "FOLK", "FOND", "FONT", "FOOD", "FOOL",
|
||||
"FOOT", "FORD", "FORE", "FORK", "FORM", "FORT", "FOSS", "FOUL",
|
||||
"FOUR", "FOWL", "FRAU", "FRAY", "FRED", "FREE", "FRET", "FREY",
|
||||
"FROG", "FROM", "FUEL", "FULL", "FUME", "FUND", "FUNK", "FURY",
|
||||
"FUSE", "FUSS", "GAFF", "GAGE", "GAIL", "GAIN", "GAIT", "GALA",
|
||||
"GALE", "GALL", "GALT", "GAME", "GANG", "GARB", "GARY", "GASH",
|
||||
"GATE", "GAUL", "GAUR", "GAVE", "GAWK", "GEAR", "GELD", "GENE",
|
||||
"GENT", "GERM", "GETS", "GIBE", "GIFT", "GILD", "GILL", "GILT",
|
||||
"GINA", "GIRD", "GIRL", "GIST", "GIVE", "GLAD", "GLEE", "GLEN",
|
||||
"GLIB", "GLOB", "GLOM", "GLOW", "GLUE", "GLUM", "GLUT", "GOAD",
|
||||
"GOAL", "GOAT", "GOER", "GOES", "GOLD", "GOLF", "GONE", "GONG",
|
||||
"GOOD", "GOOF", "GORE", "GORY", "GOSH", "GOUT", "GOWN", "GRAB",
|
||||
"GRAD", "GRAY", "GREG", "GREW", "GREY", "GRID", "GRIM", "GRIN",
|
||||
"GRIT", "GROW", "GRUB", "GULF", "GULL", "GUNK", "GURU", "GUSH",
|
||||
"GUST", "GWEN", "GWYN", "HAAG", "HAAS", "HACK", "HAIL", "HAIR",
|
||||
"HALE", "HALF", "HALL", "HALO", "HALT", "HAND", "HANG", "HANK",
|
||||
"HANS", "HARD", "HARK", "HARM", "HART", "HASH", "HAST", "HATE",
|
||||
"HATH", "HAUL", "HAVE", "HAWK", "HAYS", "HEAD", "HEAL", "HEAR",
|
||||
"HEAT", "HEBE", "HECK", "HEED", "HEEL", "HEFT", "HELD", "HELL",
|
||||
"HELM", "HERB", "HERD", "HERE", "HERO", "HERS", "HESS", "HEWN",
|
||||
"HICK", "HIDE", "HIGH", "HIKE", "HILL", "HILT", "HIND", "HINT",
|
||||
"HIRE", "HISS", "HIVE", "HOBO", "HOCK", "HOFF", "HOLD", "HOLE",
|
||||
"HOLM", "HOLT", "HOME", "HONE", "HONK", "HOOD", "HOOF", "HOOK",
|
||||
"HOOT", "HORN", "HOSE", "HOST", "HOUR", "HOVE", "HOWE", "HOWL",
|
||||
"HOYT", "HUCK", "HUED", "HUFF", "HUGE", "HUGH", "HUGO", "HULK",
|
||||
"HULL", "HUNK", "HUNT", "HURD", "HURL", "HURT", "HUSH", "HYDE",
|
||||
"HYMN", "IBIS", "ICON", "IDEA", "IDLE", "IFFY", "INCA", "INCH",
|
||||
"INTO", "IONS", "IOTA", "IOWA", "IRIS", "IRMA", "IRON", "ISLE",
|
||||
"ITCH", "ITEM", "IVAN", "JACK", "JADE", "JAIL", "JAKE", "JANE",
|
||||
"JAVA", "JEAN", "JEFF", "JERK", "JESS", "JEST", "JIBE", "JILL",
|
||||
"JILT", "JIVE", "JOAN", "JOBS", "JOCK", "JOEL", "JOEY", "JOHN",
|
||||
"JOIN", "JOKE", "JOLT", "JOVE", "JUDD", "JUDE", "JUDO", "JUDY",
|
||||
"JUJU", "JUKE", "JULY", "JUNE", "JUNK", "JUNO", "JURY", "JUST",
|
||||
"JUTE", "KAHN", "KALE", "KANE", "KANT", "KARL", "KATE", "KEEL",
|
||||
"KEEN", "KENO", "KENT", "KERN", "KERR", "KEYS", "KICK", "KILL",
|
||||
"KIND", "KING", "KIRK", "KISS", "KITE", "KLAN", "KNEE", "KNEW",
|
||||
"KNIT", "KNOB", "KNOT", "KNOW", "KOCH", "KONG", "KUDO", "KURD",
|
||||
"KURT", "KYLE", "LACE", "LACK", "LACY", "LADY", "LAID", "LAIN",
|
||||
"LAIR", "LAKE", "LAMB", "LAME", "LAND", "LANE", "LANG", "LARD",
|
||||
"LARK", "LASS", "LAST", "LATE", "LAUD", "LAVA", "LAWN", "LAWS",
|
||||
"LAYS", "LEAD", "LEAF", "LEAK", "LEAN", "LEAR", "LEEK", "LEER",
|
||||
"LEFT", "LEND", "LENS", "LENT", "LEON", "LESK", "LESS", "LEST",
|
||||
"LETS", "LIAR", "LICE", "LICK", "LIED", "LIEN", "LIES", "LIEU",
|
||||
"LIFE", "LIFT", "LIKE", "LILA", "LILT", "LILY", "LIMA", "LIMB",
|
||||
"LIME", "LIND", "LINE", "LINK", "LINT", "LION", "LISA", "LIST",
|
||||
"LIVE", "LOAD", "LOAF", "LOAM", "LOAN", "LOCK", "LOFT", "LOGE",
|
||||
"LOIS", "LOLA", "LONE", "LONG", "LOOK", "LOON", "LOOT", "LORD",
|
||||
"LORE", "LOSE", "LOSS", "LOST", "LOUD", "LOVE", "LOWE", "LUCK",
|
||||
"LUCY", "LUGE", "LUKE", "LULU", "LUND", "LUNG", "LURA", "LURE",
|
||||
"LURK", "LUSH", "LUST", "LYLE", "LYNN", "LYON", "LYRA", "MACE",
|
||||
"MADE", "MAGI", "MAID", "MAIL", "MAIN", "MAKE", "MALE", "MALI",
|
||||
"MALL", "MALT", "MANA", "MANN", "MANY", "MARC", "MARE", "MARK",
|
||||
"MARS", "MART", "MARY", "MASH", "MASK", "MASS", "MAST", "MATE",
|
||||
"MATH", "MAUL", "MAYO", "MEAD", "MEAL", "MEAN", "MEAT", "MEEK",
|
||||
"MEET", "MELD", "MELT", "MEMO", "MEND", "MENU", "MERT", "MESH",
|
||||
"MESS", "MICE", "MIKE", "MILD", "MILE", "MILK", "MILL", "MILT",
|
||||
"MIMI", "MIND", "MINE", "MINI", "MINK", "MINT", "MIRE", "MISS",
|
||||
"MIST", "MITE", "MITT", "MOAN", "MOAT", "MOCK", "MODE", "MOLD",
|
||||
"MOLE", "MOLL", "MOLT", "MONA", "MONK", "MONT", "MOOD", "MOON",
|
||||
"MOOR", "MOOT", "MORE", "MORN", "MORT", "MOSS", "MOST", "MOTH",
|
||||
"MOVE", "MUCH", "MUCK", "MUDD", "MUFF", "MULE", "MULL", "MURK",
|
||||
"MUSH", "MUST", "MUTE", "MUTT", "MYRA", "MYTH", "NAGY", "NAIL",
|
||||
"NAIR", "NAME", "NARY", "NASH", "NAVE", "NAVY", "NEAL", "NEAR",
|
||||
"NEAT", "NECK", "NEED", "NEIL", "NELL", "NEON", "NERO", "NESS",
|
||||
"NEST", "NEWS", "NEWT", "NIBS", "NICE", "NICK", "NILE", "NINA",
|
||||
"NINE", "NOAH", "NODE", "NOEL", "NOLL", "NONE", "NOOK", "NOON",
|
||||
"NORM", "NOSE", "NOTE", "NOUN", "NOVA", "NUDE", "NULL", "NUMB",
|
||||
"OATH", "OBEY", "OBOE", "ODIN", "OHIO", "OILY", "OINT", "OKAY",
|
||||
"OLAF", "OLDY", "OLGA", "OLIN", "OMAN", "OMEN", "OMIT", "ONCE",
|
||||
"ONES", "ONLY", "ONTO", "ONUS", "ORAL", "ORGY", "OSLO", "OTIS",
|
||||
"OTTO", "OUCH", "OUST", "OUTS", "OVAL", "OVEN", "OVER", "OWLY",
|
||||
"OWNS", "QUAD", "QUIT", "QUOD", "RACE", "RACK", "RACY", "RAFT",
|
||||
"RAGE", "RAID", "RAIL", "RAIN", "RAKE", "RANK", "RANT", "RARE",
|
||||
"RASH", "RATE", "RAVE", "RAYS", "READ", "REAL", "REAM", "REAR",
|
||||
"RECK", "REED", "REEF", "REEK", "REEL", "REID", "REIN", "RENA",
|
||||
"REND", "RENT", "REST", "RICE", "RICH", "RICK", "RIDE", "RIFT",
|
||||
"RILL", "RIME", "RING", "RINK", "RISE", "RISK", "RITE", "ROAD",
|
||||
"ROAM", "ROAR", "ROBE", "ROCK", "RODE", "ROIL", "ROLL", "ROME",
|
||||
"ROOD", "ROOF", "ROOK", "ROOM", "ROOT", "ROSA", "ROSE", "ROSS",
|
||||
"ROSY", "ROTH", "ROUT", "ROVE", "ROWE", "ROWS", "RUBE", "RUBY",
|
||||
"RUDE", "RUDY", "RUIN", "RULE", "RUNG", "RUNS", "RUNT", "RUSE",
|
||||
"RUSH", "RUSK", "RUSS", "RUST", "RUTH", "SACK", "SAFE", "SAGE",
|
||||
"SAID", "SAIL", "SALE", "SALK", "SALT", "SAME", "SAND", "SANE",
|
||||
"SANG", "SANK", "SARA", "SAUL", "SAVE", "SAYS", "SCAN", "SCAR",
|
||||
"SCAT", "SCOT", "SEAL", "SEAM", "SEAR", "SEAT", "SEED", "SEEK",
|
||||
"SEEM", "SEEN", "SEES", "SELF", "SELL", "SEND", "SENT", "SETS",
|
||||
"SEWN", "SHAG", "SHAM", "SHAW", "SHAY", "SHED", "SHIM", "SHIN",
|
||||
"SHOD", "SHOE", "SHOT", "SHOW", "SHUN", "SHUT", "SICK", "SIDE",
|
||||
"SIFT", "SIGH", "SIGN", "SILK", "SILL", "SILO", "SILT", "SINE",
|
||||
"SING", "SINK", "SIRE", "SITE", "SITS", "SITU", "SKAT", "SKEW",
|
||||
"SKID", "SKIM", "SKIN", "SKIT", "SLAB", "SLAM", "SLAT", "SLAY",
|
||||
"SLED", "SLEW", "SLID", "SLIM", "SLIT", "SLOB", "SLOG", "SLOT",
|
||||
"SLOW", "SLUG", "SLUM", "SLUR", "SMOG", "SMUG", "SNAG", "SNOB",
|
||||
"SNOW", "SNUB", "SNUG", "SOAK", "SOAR", "SOCK", "SODA", "SOFA",
|
||||
"SOFT", "SOIL", "SOLD", "SOME", "SONG", "SOON", "SOOT", "SORE",
|
||||
"SORT", "SOUL", "SOUR", "SOWN", "STAB", "STAG", "STAN", "STAR",
|
||||
"STAY", "STEM", "STEW", "STIR", "STOW", "STUB", "STUN", "SUCH",
|
||||
"SUDS", "SUIT", "SULK", "SUMS", "SUNG", "SUNK", "SURE", "SURF",
|
||||
"SWAB", "SWAG", "SWAM", "SWAN", "SWAT", "SWAY", "SWIM", "SWUM",
|
||||
"TACK", "TACT", "TAIL", "TAKE", "TALE", "TALK", "TALL", "TANK",
|
||||
"TASK", "TATE", "TAUT", "TEAL", "TEAM", "TEAR", "TECH", "TEEM",
|
||||
"TEEN", "TEET", "TELL", "TEND", "TENT", "TERM", "TERN", "TESS",
|
||||
"TEST", "THAN", "THAT", "THEE", "THEM", "THEN", "THEY", "THIN",
|
||||
"THIS", "THUD", "THUG", "TICK", "TIDE", "TIDY", "TIED", "TIER",
|
||||
"TILE", "TILL", "TILT", "TIME", "TINA", "TINE", "TINT", "TINY",
|
||||
"TIRE", "TOAD", "TOGO", "TOIL", "TOLD", "TOLL", "TONE", "TONG",
|
||||
"TONY", "TOOK", "TOOL", "TOOT", "TORE", "TORN", "TOTE", "TOUR",
|
||||
"TOUT", "TOWN", "TRAG", "TRAM", "TRAY", "TREE", "TREK", "TRIG",
|
||||
"TRIM", "TRIO", "TROD", "TROT", "TROY", "TRUE", "TUBA", "TUBE",
|
||||
"TUCK", "TUFT", "TUNA", "TUNE", "TUNG", "TURF", "TURN", "TUSK",
|
||||
"TWIG", "TWIN", "TWIT", "ULAN", "UNIT", "URGE", "USED", "USER",
|
||||
"USES", "UTAH", "VAIL", "VAIN", "VALE", "VARY", "VASE", "VAST",
|
||||
"VEAL", "VEDA", "VEIL", "VEIN", "VEND", "VENT", "VERB", "VERY",
|
||||
"VETO", "VICE", "VIEW", "VINE", "VISE", "VOID", "VOLT", "VOTE",
|
||||
"WACK", "WADE", "WAGE", "WAIL", "WAIT", "WAKE", "WALE", "WALK",
|
||||
"WALL", "WALT", "WAND", "WANE", "WANG", "WANT", "WARD", "WARM",
|
||||
"WARN", "WART", "WASH", "WAST", "WATS", "WATT", "WAVE", "WAVY",
|
||||
"WAYS", "WEAK", "WEAL", "WEAN", "WEAR", "WEED", "WEEK", "WEIR",
|
||||
"WELD", "WELL", "WELT", "WENT", "WERE", "WERT", "WEST", "WHAM",
|
||||
"WHAT", "WHEE", "WHEN", "WHET", "WHOA", "WHOM", "WICK", "WIFE",
|
||||
"WILD", "WILL", "WIND", "WINE", "WING", "WINK", "WINO", "WIRE",
|
||||
"WISE", "WISH", "WITH", "WOLF", "WONT", "WOOD", "WOOL", "WORD",
|
||||
"WORE", "WORK", "WORM", "WORN", "WOVE", "WRIT", "WYNN", "YALE",
|
||||
"YANG", "YANK", "YARD", "YARN", "YAWL", "YAWN", "YEAH", "YEAR",
|
||||
"YELL", "YOGA", "YOKE" ]
|
||||
|
||||
if __name__=='__main__':
|
||||
data = [('EB33F77EE73D4053', 'TIDE ITCH SLOW REIN RULE MOT'),
|
||||
('CCAC2AED591056BE4F90FD441C534766',
|
||||
'RASH BUSH MILK LOOK BAD BRIM AVID GAFF BAIT ROT POD LOVE'),
|
||||
('EFF81F9BFBC65350920CDD7416DE8009',
|
||||
'TROD MUTE TAIL WARM CHAR KONG HAAG CITY BORE O TEAL AWL')
|
||||
]
|
||||
|
||||
for key, words in data:
|
||||
print 'Trying key', key
|
||||
key=binascii.a2b_hex(key)
|
||||
w2=key_to_english(key)
|
||||
if w2!=words:
|
||||
print 'key_to_english fails on key', repr(key), ', producing', str(w2)
|
||||
k2=english_to_key(words)
|
||||
if k2!=key:
|
||||
print 'english_to_key fails on key', repr(key), ', producing', repr(k2)
|
||||
|
||||
|
@ -1,16 +0,0 @@
|
||||
"""Miscellaneous modules
|
||||
|
||||
Contains useful modules that don't belong into any of the
|
||||
other Crypto.* subpackages.
|
||||
|
||||
Crypto.Util.number Number-theoretic functions (primality testing, etc.)
|
||||
Crypto.Util.randpool Random number generation
|
||||
Crypto.Util.RFC1751 Converts between 128-bit keys and human-readable
|
||||
strings of words.
|
||||
|
||||
"""
|
||||
|
||||
__all__ = ['randpool', 'RFC1751', 'number']
|
||||
|
||||
__revision__ = "$Id: __init__.py,v 1.4 2003/02/28 15:26:00 akuchling Exp $"
|
||||
|
@ -1,84 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
from pyutil.assertutil import _assert, precondition, postcondition
|
||||
from pyutil.randutil import insecurerandstr
|
||||
from pyutil import benchutil
|
||||
|
||||
from allmydata.Crypto.Cipher import AES
|
||||
|
||||
MODE_CTR = AES.MODE_CTR # MODE_CTR is same value for all ciphers in pycrypto 2.0.1
|
||||
|
||||
class CipherRunner:
|
||||
def __init__(self, ciph, mode):
|
||||
if not ciph.key_size: ciph.key_size = 16
|
||||
self.ciph = ciph
|
||||
self.mode = mode
|
||||
self.counterstart = None
|
||||
self.key = None
|
||||
self.text = None
|
||||
self.obj = None
|
||||
self.obj2 = None
|
||||
|
||||
def init(self, n):
|
||||
precondition(self.ciph.key_size, self.ciph.key_size)
|
||||
self.key = insecurerandstr(self.ciph.key_size)
|
||||
if self.mode == MODE_CTR:
|
||||
self.counterstart = insecurerandstr(self.ciph.block_size)
|
||||
_assert(self.key, self.key)
|
||||
self.text = insecurerandstr(n)
|
||||
if self.mode == MODE_CTR:
|
||||
self.obj = self.ciph.new(self.key, self.mode, counterstart=self.counterstart)
|
||||
else:
|
||||
self.obj = self.ciph.new(self.key, self.mode)
|
||||
if self.mode == MODE_CTR:
|
||||
self.obj2 = self.ciph.new(self.key, self.mode, counterstart=self.counterstart)
|
||||
else:
|
||||
self.obj2 = self.ciph.new(self.key, self.mode)
|
||||
|
||||
def construct_then_encrypt(self, n):
|
||||
assert len(self.text) == n
|
||||
if self.mode == MODE_CTR:
|
||||
self.obj = self.ciph.new(self.key, self.mode, counterstart=self.counterstart)
|
||||
else:
|
||||
self.obj = self.ciph.new(self.key, self.mode)
|
||||
return self.obj.encrypt(self.text)
|
||||
|
||||
def encrypt(self, n):
|
||||
assert len(self.text) == n
|
||||
return self.obj.encrypt(self.text)
|
||||
|
||||
def decrypt(self, n):
|
||||
assert len(self.text) == n
|
||||
return self.obj.decrypt(self.text)
|
||||
|
||||
def encrypt_then_decrypt_then_compare(self, n):
|
||||
assert len(self.text) == n
|
||||
ciphertext = self.obj.encrypt(self.text)
|
||||
decrypted = self.obj2.decrypt(ciphertext)
|
||||
if decrypted != self.text:
|
||||
raise "FAILURE! decrypted does match original plaintext, self.text[:64]: %r, decrypted[:64]: %r" % (self.text[:64], decrypted[:64],)
|
||||
|
||||
def construct_then_encrypt_then_decrypt_then_compare(self, n):
|
||||
assert len(self.text) == n
|
||||
if self.mode == MODE_CTR:
|
||||
self.obj = self.ciph.new(self.key, self.mode, counterstart=self.counterstart)
|
||||
else:
|
||||
self.obj = self.ciph.new(self.key, self.mode)
|
||||
if self.mode == MODE_CTR:
|
||||
self.obj2 = self.ciph.new(self.key, self.mode, counterstart=self.counterstart)
|
||||
else:
|
||||
self.obj2 = self.ciph.new(self.key, self.mode)
|
||||
ciphertext = self.obj.encrypt(self.text)
|
||||
decrypted = self.obj2.decrypt(ciphertext)
|
||||
if decrypted != self.text:
|
||||
raise "FAILURE! decrypted does match original plaintext, self.text[:64]: %r, decrypted[:64]: %r" % (self.text[:64], decrypted[:64],)
|
||||
|
||||
from allmydata.Crypto.Cipher import *
|
||||
def bench_aes_ctr():
|
||||
c = CipherRunner(AES, AES.MODE_CTR)
|
||||
|
||||
for m in (c.construct_then_encrypt, c.encrypt, c.decrypt, c.encrypt_then_decrypt_then_compare, c.construct_then_encrypt_then_decrypt_then_compare,):
|
||||
print m.__name__
|
||||
for BSIZE in (2**4, 2**8, 2**10, 2**14, 2**16,):
|
||||
benchutil.rep_bench(m, BSIZE, initfunc=c.init, MAXREPS=2**14, MAXTIME=10.0)
|
||||
|
@ -1,421 +0,0 @@
|
||||
#
|
||||
# randpool.py : Cryptographically strong random number generation
|
||||
#
|
||||
# Part of the Python Cryptography Toolkit
|
||||
#
|
||||
# Distribute and use freely; there are no restrictions on further
|
||||
# dissemination and usage except those imposed by the laws of your
|
||||
# country of residence. This software is provided "as is" without
|
||||
# warranty of fitness for use or suitability for any purpose, express
|
||||
# or implied. Use at your own risk or not at all.
|
||||
#
|
||||
|
||||
__revision__ = "$Id: randpool.py,v 1.14 2004/05/06 12:56:54 akuchling Exp $"
|
||||
|
||||
import time, array, types, warnings, os.path
|
||||
from allmydata.Crypto.Util.number import long_to_bytes
|
||||
try:
|
||||
import allmydata.Crypto.Util.winrandom as winrandom
|
||||
except:
|
||||
winrandom = None
|
||||
|
||||
STIRNUM = 3
|
||||
|
||||
class RandomPool:
|
||||
"""randpool.py : Cryptographically strong random number generation.
|
||||
|
||||
The implementation here is similar to the one in PGP. To be
|
||||
cryptographically strong, it must be difficult to determine the RNG's
|
||||
output, whether in the future or the past. This is done by using
|
||||
a cryptographic hash function to "stir" the random data.
|
||||
|
||||
Entropy is gathered in the same fashion as PGP; the highest-resolution
|
||||
clock around is read and the data is added to the random number pool.
|
||||
A conservative estimate of the entropy is then kept.
|
||||
|
||||
If a cryptographically secure random source is available (/dev/urandom
|
||||
on many Unixes, Windows CryptGenRandom on most Windows), then use
|
||||
it.
|
||||
|
||||
Instance Attributes:
|
||||
bits : int
|
||||
Maximum size of pool in bits
|
||||
bytes : int
|
||||
Maximum size of pool in bytes
|
||||
entropy : int
|
||||
Number of bits of entropy in this pool.
|
||||
|
||||
Methods:
|
||||
add_event([s]) : add some entropy to the pool
|
||||
get_bytes(int) : get N bytes of random data
|
||||
randomize([N]) : get N bytes of randomness from external source
|
||||
"""
|
||||
|
||||
|
||||
def __init__(self, numbytes = 160, cipher=None, hash=None):
|
||||
if hash is None:
|
||||
from allmydata.Crypto.Hash import SHA as hash
|
||||
|
||||
# The cipher argument is vestigial; it was removed from
|
||||
# version 1.1 so RandomPool would work even in the limited
|
||||
# exportable subset of the code
|
||||
if cipher is not None:
|
||||
warnings.warn("'cipher' parameter is no longer used")
|
||||
|
||||
if isinstance(hash, types.StringType):
|
||||
# ugly hack to force __import__ to give us the end-path module
|
||||
hash = __import__('allmydata.Crypto.Hash.'+hash,
|
||||
None, None, ['new'])
|
||||
warnings.warn("'hash' parameter should now be a hashing module")
|
||||
|
||||
self.bytes = numbytes
|
||||
self.bits = self.bytes*8
|
||||
self.entropy = 0
|
||||
self._hash = hash
|
||||
|
||||
# Construct an array to hold the random pool,
|
||||
# initializing it to 0.
|
||||
self._randpool = array.array('B', [0]*self.bytes)
|
||||
|
||||
self._event1 = self._event2 = 0
|
||||
self._addPos = 0
|
||||
self._getPos = hash.digest_size
|
||||
self._lastcounter=time.time()
|
||||
self.__counter = 0
|
||||
|
||||
self._measureTickSize() # Estimate timer resolution
|
||||
self._randomize()
|
||||
|
||||
def _updateEntropyEstimate(self, nbits):
|
||||
self.entropy += nbits
|
||||
if self.entropy < 0:
|
||||
self.entropy = 0
|
||||
elif self.entropy > self.bits:
|
||||
self.entropy = self.bits
|
||||
|
||||
def _randomize(self, N = 0, devname = '/dev/urandom'):
|
||||
"""_randomize(N, DEVNAME:device-filepath)
|
||||
collects N bits of randomness from some entropy source (e.g.,
|
||||
/dev/urandom on Unixes that have it, Windows CryptoAPI
|
||||
CryptGenRandom, etc)
|
||||
DEVNAME is optional, defaults to /dev/urandom. You can change it
|
||||
to /dev/random if you want to block till you get enough
|
||||
entropy.
|
||||
"""
|
||||
data = ''
|
||||
if N <= 0:
|
||||
nbytes = int((self.bits - self.entropy)/8+0.5)
|
||||
else:
|
||||
nbytes = int(N/8+0.5)
|
||||
if winrandom:
|
||||
# Windows CryptGenRandom provides random data.
|
||||
data = winrandom.new().get_bytes(nbytes)
|
||||
elif os.path.exists(devname):
|
||||
# Many OSes support a /dev/urandom device
|
||||
try:
|
||||
f=open(devname)
|
||||
data=f.read(nbytes)
|
||||
f.close()
|
||||
except IOError, (num, msg):
|
||||
if num!=2: raise IOError, (num, msg)
|
||||
# If the file wasn't found, ignore the error
|
||||
if data:
|
||||
self._addBytes(data)
|
||||
# Entropy estimate: The number of bits of
|
||||
# data obtained from the random source.
|
||||
self._updateEntropyEstimate(8*len(data))
|
||||
self.stir_n() # Wash the random pool
|
||||
|
||||
def randomize(self, N=0):
|
||||
"""randomize(N:int)
|
||||
use the class entropy source to get some entropy data.
|
||||
This is overridden by KeyboardRandomize().
|
||||
"""
|
||||
return self._randomize(N)
|
||||
|
||||
def stir_n(self, N = STIRNUM):
|
||||
"""stir_n(N)
|
||||
stirs the random pool N times
|
||||
"""
|
||||
for i in xrange(N):
|
||||
self.stir()
|
||||
|
||||
def stir (self, s = ''):
|
||||
"""stir(s:string)
|
||||
Mix up the randomness pool. This will call add_event() twice,
|
||||
but out of paranoia the entropy attribute will not be
|
||||
increased. The optional 's' parameter is a string that will
|
||||
be hashed with the randomness pool.
|
||||
"""
|
||||
|
||||
entropy=self.entropy # Save inital entropy value
|
||||
self.add_event()
|
||||
|
||||
# Loop over the randomness pool: hash its contents
|
||||
# along with a counter, and add the resulting digest
|
||||
# back into the pool.
|
||||
for i in range(self.bytes / self._hash.digest_size):
|
||||
h = self._hash.new(self._randpool)
|
||||
h.update(str(self.__counter) + str(i) + str(self._addPos) + s)
|
||||
self._addBytes( h.digest() )
|
||||
self.__counter = (self.__counter + 1) & 0xFFFFffffL
|
||||
|
||||
self._addPos, self._getPos = 0, self._hash.digest_size
|
||||
self.add_event()
|
||||
|
||||
# Restore the old value of the entropy.
|
||||
self.entropy=entropy
|
||||
|
||||
|
||||
def get_bytes (self, N):
|
||||
"""get_bytes(N:int) : string
|
||||
Return N bytes of random data.
|
||||
"""
|
||||
|
||||
s=''
|
||||
i, pool = self._getPos, self._randpool
|
||||
h=self._hash.new()
|
||||
dsize = self._hash.digest_size
|
||||
num = N
|
||||
while num > 0:
|
||||
h.update( self._randpool[i:i+dsize] )
|
||||
s = s + h.digest()
|
||||
num = num - dsize
|
||||
i = (i + dsize) % self.bytes
|
||||
if i<dsize:
|
||||
self.stir()
|
||||
i=self._getPos
|
||||
|
||||
self._getPos = i
|
||||
self._updateEntropyEstimate(- 8*N)
|
||||
return s[:N]
|
||||
|
||||
|
||||
def add_event(self, s=''):
|
||||
"""add_event(s:string)
|
||||
Add an event to the random pool. The current time is stored
|
||||
between calls and used to estimate the entropy. The optional
|
||||
's' parameter is a string that will also be XORed into the pool.
|
||||
Returns the estimated number of additional bits of entropy gain.
|
||||
"""
|
||||
event = time.time()*1000
|
||||
delta = self._noise()
|
||||
s = (s + long_to_bytes(event) +
|
||||
4*chr(0xaa) + long_to_bytes(delta) )
|
||||
self._addBytes(s)
|
||||
if event==self._event1 and event==self._event2:
|
||||
# If events are coming too closely together, assume there's
|
||||
# no effective entropy being added.
|
||||
bits=0
|
||||
else:
|
||||
# Count the number of bits in delta, and assume that's the entropy.
|
||||
bits=0
|
||||
while delta:
|
||||
delta, bits = delta>>1, bits+1
|
||||
if bits>8: bits=8
|
||||
|
||||
self._event1, self._event2 = event, self._event1
|
||||
|
||||
self._updateEntropyEstimate(bits)
|
||||
return bits
|
||||
|
||||
# Private functions
|
||||
def _noise(self):
|
||||
# Adds a bit of noise to the random pool, by adding in the
|
||||
# current time and CPU usage of this process.
|
||||
# The difference from the previous call to _noise() is taken
|
||||
# in an effort to estimate the entropy.
|
||||
t=time.time()
|
||||
delta = (t - self._lastcounter)/self._ticksize*1e6
|
||||
self._lastcounter = t
|
||||
self._addBytes(long_to_bytes(long(1000*time.time())))
|
||||
self._addBytes(long_to_bytes(long(1000*time.clock())))
|
||||
self._addBytes(long_to_bytes(long(1000*time.time())))
|
||||
self._addBytes(long_to_bytes(long(delta)))
|
||||
|
||||
# Reduce delta to a maximum of 8 bits so we don't add too much
|
||||
# entropy as a result of this call.
|
||||
delta=delta % 0xff
|
||||
return int(delta)
|
||||
|
||||
|
||||
def _measureTickSize(self):
|
||||
# _measureTickSize() tries to estimate a rough average of the
|
||||
# resolution of time that you can see from Python. It does
|
||||
# this by measuring the time 100 times, computing the delay
|
||||
# between measurements, and taking the median of the resulting
|
||||
# list. (We also hash all the times and add them to the pool)
|
||||
interval = [None] * 100
|
||||
h = self._hash.new(`(id(self),id(interval))`)
|
||||
|
||||
# Compute 100 differences
|
||||
t=time.time()
|
||||
h.update(`t`)
|
||||
i = 0
|
||||
j = 0
|
||||
while i < 100:
|
||||
t2=time.time()
|
||||
h.update(`(i,j,t2)`)
|
||||
j += 1
|
||||
delta=int((t2-t)*1e6)
|
||||
if delta:
|
||||
interval[i] = delta
|
||||
i += 1
|
||||
t=t2
|
||||
|
||||
# Take the median of the array of intervals
|
||||
interval.sort()
|
||||
self._ticksize=interval[len(interval)/2]
|
||||
h.update(`(interval,self._ticksize)`)
|
||||
# mix in the measurement times and wash the random pool
|
||||
self.stir(h.digest())
|
||||
|
||||
def _addBytes(self, s):
|
||||
"XOR the contents of the string S into the random pool"
|
||||
i, pool = self._addPos, self._randpool
|
||||
for j in range(0, len(s)):
|
||||
pool[i]=pool[i] ^ ord(s[j])
|
||||
i=(i+1) % self.bytes
|
||||
self._addPos = i
|
||||
|
||||
# Deprecated method names: remove in PCT 2.1 or later.
|
||||
def getBytes(self, N):
|
||||
warnings.warn("getBytes() method replaced by get_bytes()",
|
||||
DeprecationWarning)
|
||||
return self.get_bytes(N)
|
||||
|
||||
def addEvent (self, event, s=""):
|
||||
warnings.warn("addEvent() method replaced by add_event()",
|
||||
DeprecationWarning)
|
||||
return self.add_event(s + str(event))
|
||||
|
||||
class PersistentRandomPool (RandomPool):
|
||||
def __init__ (self, filename=None, *args, **kwargs):
|
||||
RandomPool.__init__(self, *args, **kwargs)
|
||||
self.filename = filename
|
||||
if filename:
|
||||
try:
|
||||
# the time taken to open and read the file might have
|
||||
# a little disk variability, modulo disk/kernel caching...
|
||||
f=open(filename, 'rb')
|
||||
self.add_event()
|
||||
data = f.read()
|
||||
self.add_event()
|
||||
# mix in the data from the file and wash the random pool
|
||||
self.stir(data)
|
||||
f.close()
|
||||
except IOError:
|
||||
# Oh, well; the file doesn't exist or is unreadable, so
|
||||
# we'll just ignore it.
|
||||
pass
|
||||
|
||||
def save(self):
|
||||
if self.filename == "":
|
||||
raise ValueError, "No filename set for this object"
|
||||
# wash the random pool before save, provides some forward secrecy for
|
||||
# old values of the pool.
|
||||
self.stir_n()
|
||||
f=open(self.filename, 'wb')
|
||||
self.add_event()
|
||||
f.write(self._randpool.tostring())
|
||||
f.close()
|
||||
self.add_event()
|
||||
# wash the pool again, provide some protection for future values
|
||||
self.stir()
|
||||
|
||||
# non-echoing Windows keyboard entry
|
||||
_kb = 0
|
||||
if not _kb:
|
||||
try:
|
||||
import msvcrt
|
||||
class KeyboardEntry:
|
||||
def getch(self):
|
||||
c = msvcrt.getch()
|
||||
if c in ('\000', '\xe0'):
|
||||
# function key
|
||||
c += msvcrt.getch()
|
||||
return c
|
||||
def close(self, delay = 0):
|
||||
if delay:
|
||||
time.sleep(delay)
|
||||
while msvcrt.kbhit():
|
||||
msvcrt.getch()
|
||||
_kb = 1
|
||||
except:
|
||||
pass
|
||||
|
||||
# non-echoing Posix keyboard entry
|
||||
if not _kb:
|
||||
try:
|
||||
import termios
|
||||
class KeyboardEntry:
|
||||
def __init__(self, fd = 0):
|
||||
self._fd = fd
|
||||
self._old = termios.tcgetattr(fd)
|
||||
new = termios.tcgetattr(fd)
|
||||
new[3]=new[3] & ~termios.ICANON & ~termios.ECHO
|
||||
termios.tcsetattr(fd, termios.TCSANOW, new)
|
||||
def getch(self):
|
||||
termios.tcflush(0, termios.TCIFLUSH) # XXX Leave this in?
|
||||
return os.read(self._fd, 1)
|
||||
def close(self, delay = 0):
|
||||
if delay:
|
||||
time.sleep(delay)
|
||||
termios.tcflush(self._fd, termios.TCIFLUSH)
|
||||
termios.tcsetattr(self._fd, termios.TCSAFLUSH, self._old)
|
||||
_kb = 1
|
||||
except:
|
||||
pass
|
||||
|
||||
class KeyboardRandomPool (PersistentRandomPool):
|
||||
def __init__(self, *args, **kwargs):
|
||||
PersistentRandomPool.__init__(self, *args, **kwargs)
|
||||
|
||||
def randomize(self, N = 0):
|
||||
"Adds N bits of entropy to random pool. If N is 0, fill up pool."
|
||||
import os, string, time
|
||||
if N <= 0:
|
||||
bits = self.bits - self.entropy
|
||||
else:
|
||||
bits = N*8
|
||||
if bits == 0:
|
||||
return
|
||||
print bits,'bits of entropy are now required. Please type on the keyboard'
|
||||
print 'until enough randomness has been accumulated.'
|
||||
kb = KeyboardEntry()
|
||||
s='' # We'll save the characters typed and add them to the pool.
|
||||
hash = self._hash
|
||||
e = 0
|
||||
try:
|
||||
while e < bits:
|
||||
temp=str(bits-e).rjust(6)
|
||||
os.write(1, temp)
|
||||
s=s+kb.getch()
|
||||
e += self.add_event(s)
|
||||
os.write(1, 6*chr(8))
|
||||
self.add_event(s+hash.new(s).digest() )
|
||||
finally:
|
||||
kb.close()
|
||||
print '\n\007 Enough. Please wait a moment.\n'
|
||||
self.stir_n() # wash the random pool.
|
||||
kb.close(4)
|
||||
|
||||
if __name__ == '__main__':
|
||||
pool = RandomPool()
|
||||
print 'random pool entropy', pool.entropy, 'bits'
|
||||
pool.add_event('something')
|
||||
print `pool.get_bytes(100)`
|
||||
import tempfile, os
|
||||
fname = tempfile.mktemp()
|
||||
pool = KeyboardRandomPool(filename=fname)
|
||||
print 'keyboard random pool entropy', pool.entropy, 'bits'
|
||||
pool.randomize()
|
||||
print 'keyboard random pool entropy', pool.entropy, 'bits'
|
||||
pool.randomize(128)
|
||||
pool.save()
|
||||
saved = open(fname, 'rb').read()
|
||||
print 'saved', `saved`
|
||||
print 'pool ', `pool._randpool.tostring()`
|
||||
newpool = PersistentRandomPool(fname)
|
||||
print 'persistent random pool entropy', pool.entropy, 'bits'
|
||||
os.remove(fname)
|
@ -1,495 +0,0 @@
|
||||
#
|
||||
# test.py : Functions used for testing the modules
|
||||
#
|
||||
# Part of the Python Cryptography Toolkit
|
||||
#
|
||||
# Distribute and use freely; there are no restrictions on further
|
||||
# dissemination and usage except those imposed by the laws of your
|
||||
# country of residence. This software is provided "as is" without
|
||||
# warranty of fitness for use or suitability for any purpose, express
|
||||
# or implied. Use at your own risk or not at all.
|
||||
#
|
||||
|
||||
__revision__ = "$Id: test.py,v 1.16 2004/08/13 22:24:18 akuchling Exp $"
|
||||
|
||||
import binascii
|
||||
import random
|
||||
import string
|
||||
import testdata
|
||||
|
||||
from allmydata.Crypto.Cipher import *
|
||||
from allmydata.Crypto.Util.number import long_to_bytes
|
||||
|
||||
def die(string):
|
||||
import sys
|
||||
print '***ERROR: ', string
|
||||
# sys.exit(0) # Will default to continuing onward...
|
||||
|
||||
def print_timing (size, delta, verbose):
|
||||
if verbose:
|
||||
if delta == 0:
|
||||
print 'Unable to measure time -- elapsed time too small'
|
||||
else:
|
||||
print '%.2f K/sec' % (size/delta)
|
||||
|
||||
def exerciseBlockCipher(cipher, verbose):
|
||||
import string, time
|
||||
try:
|
||||
ciph = eval(cipher)
|
||||
except NameError:
|
||||
print cipher, 'module not available'
|
||||
return None
|
||||
print cipher+ ':'
|
||||
str='1' # Build 128K of test data
|
||||
for i in xrange(0, 17):
|
||||
str=str+str
|
||||
if ciph.key_size==0: ciph.key_size=16
|
||||
password = 'password12345678Extra text for password'[0:ciph.key_size]
|
||||
IV = 'Test IV Test IV Test IV Test'[0:ciph.block_size]
|
||||
|
||||
if verbose: print ' ECB mode:',
|
||||
obj=ciph.new(password, ciph.MODE_ECB)
|
||||
if obj.block_size != ciph.block_size:
|
||||
die("Module and cipher object block_size don't match")
|
||||
|
||||
text='1234567812345678'[0:ciph.block_size]
|
||||
c=obj.encrypt(text)
|
||||
if (obj.decrypt(c)!=text): die('Error encrypting "'+text+'"')
|
||||
text='KuchlingKuchling'[0:ciph.block_size]
|
||||
c=obj.encrypt(text)
|
||||
if (obj.decrypt(c)!=text): die('Error encrypting "'+text+'"')
|
||||
text='NotTodayNotEver!'[0:ciph.block_size]
|
||||
c=obj.encrypt(text)
|
||||
if (obj.decrypt(c)!=text): die('Error encrypting "'+text+'"')
|
||||
|
||||
start=time.time()
|
||||
s=obj.encrypt(str)
|
||||
s2=obj.decrypt(s)
|
||||
end=time.time()
|
||||
if (str!=s2):
|
||||
die('Error in resulting plaintext from ECB mode')
|
||||
print_timing(256, end-start, verbose)
|
||||
del obj
|
||||
|
||||
if verbose: print ' CFB mode:',
|
||||
obj1=ciph.new(password, ciph.MODE_CFB, IV)
|
||||
obj2=ciph.new(password, ciph.MODE_CFB, IV)
|
||||
start=time.time()
|
||||
ciphertext=obj1.encrypt(str[0:65536])
|
||||
plaintext=obj2.decrypt(ciphertext)
|
||||
end=time.time()
|
||||
if (plaintext!=str[0:65536]):
|
||||
die('Error in resulting plaintext from CFB mode')
|
||||
print_timing(64, end-start, verbose)
|
||||
del obj1, obj2
|
||||
|
||||
if verbose: print ' CBC mode:',
|
||||
obj1=ciph.new(password, ciph.MODE_CBC, IV)
|
||||
obj2=ciph.new(password, ciph.MODE_CBC, IV)
|
||||
start=time.time()
|
||||
ciphertext=obj1.encrypt(str)
|
||||
plaintext=obj2.decrypt(ciphertext)
|
||||
end=time.time()
|
||||
if (plaintext!=str):
|
||||
die('Error in resulting plaintext from CBC mode')
|
||||
print_timing(256, end-start, verbose)
|
||||
del obj1, obj2
|
||||
|
||||
if verbose: print ' PGP mode:',
|
||||
obj1=ciph.new(password, ciph.MODE_PGP, IV)
|
||||
obj2=ciph.new(password, ciph.MODE_PGP, IV)
|
||||
start=time.time()
|
||||
ciphertext=obj1.encrypt(str)
|
||||
plaintext=obj2.decrypt(ciphertext)
|
||||
end=time.time()
|
||||
if (plaintext!=str):
|
||||
die('Error in resulting plaintext from PGP mode')
|
||||
print_timing(256, end-start, verbose)
|
||||
del obj1, obj2
|
||||
|
||||
if verbose: print ' OFB mode:',
|
||||
obj1=ciph.new(password, ciph.MODE_OFB, IV)
|
||||
obj2=ciph.new(password, ciph.MODE_OFB, IV)
|
||||
start=time.time()
|
||||
ciphertext=obj1.encrypt(str)
|
||||
plaintext=obj2.decrypt(ciphertext)
|
||||
end=time.time()
|
||||
if (plaintext!=str):
|
||||
die('Error in resulting plaintext from OFB mode')
|
||||
print_timing(256, end-start, verbose)
|
||||
del obj1, obj2
|
||||
|
||||
startctr = random.randrange(0, 2**(ciph.block_size * 8))
|
||||
|
||||
if verbose: print ' CTR mode:',
|
||||
obj1=ciph.new(password, ciph.MODE_CTR, counterstart=long_to_bytes(startctr, ciph.block_size))
|
||||
obj2=ciph.new(password, ciph.MODE_CTR, counterstart=long_to_bytes(startctr, ciph.block_size))
|
||||
start=time.time()
|
||||
ciphertext=obj1.encrypt(str)
|
||||
plaintext=obj2.decrypt(ciphertext)
|
||||
end=time.time()
|
||||
if (plaintext!=str):
|
||||
die('Error in resulting plaintext from CTR mode')
|
||||
print_timing(256, end-start, verbose)
|
||||
del obj1, obj2
|
||||
|
||||
if verbose: print ' CTR mode, variable length:',
|
||||
strv = str[:-1]
|
||||
obj1=ciph.new(password, ciph.MODE_CTR, counterstart=long_to_bytes(startctr, ciph.block_size))
|
||||
obj2=ciph.new(password, ciph.MODE_CTR, counterstart=long_to_bytes(startctr, ciph.block_size))
|
||||
start=time.time()
|
||||
ciphertext=obj1.encrypt(strv)
|
||||
plaintext=obj2.decrypt(ciphertext)
|
||||
end=time.time()
|
||||
if (plaintext!=strv):
|
||||
die('Error in resulting plaintext from CTR mode, variable length')
|
||||
print_timing(256, end-start, verbose)
|
||||
del obj1, obj2
|
||||
|
||||
if verbose: print ' CTR mode, variable length, restart:',
|
||||
strv = str[:-1]
|
||||
obj1=ciph.new(password, ciph.MODE_CTR, counterstart=long_to_bytes(startctr, ciph.block_size))
|
||||
obj2=ciph.new(password, ciph.MODE_CTR, counterstart=long_to_bytes(startctr, ciph.block_size))
|
||||
start=time.time()
|
||||
tempstrv = strv
|
||||
ciphertexta = []
|
||||
while tempstrv:
|
||||
chunksiz = random.randrange(1, len(tempstrv)+1)
|
||||
ciphertexta.append(obj1.encrypt(tempstrv[:chunksiz]))
|
||||
tempstrv = tempstrv[chunksiz:]
|
||||
ciphertext = ''.join(ciphertexta)
|
||||
plaintext=obj2.decrypt(ciphertext)
|
||||
end=time.time()
|
||||
if (len(plaintext)!=len(strv)):
|
||||
die('Error in resulting plaintext from CTR mode, variable length, restart, lenofplaintext: %s, lenofstrv: %r' % (len(plaintext), len(strv),))
|
||||
|
||||
if (plaintext!=strv):
|
||||
die('Error in resulting plaintext from CTR mode, variable length, restart, plaintext: %r, strv: %r' % (plaintext, strv,))
|
||||
print_timing(256, end-start, verbose)
|
||||
del obj1, obj2
|
||||
|
||||
# Test the IV handling
|
||||
if verbose: print ' Testing IV handling'
|
||||
obj1=ciph.new(password, ciph.MODE_CBC, IV)
|
||||
plaintext='Test'*(ciph.block_size/4)*3
|
||||
ciphertext1=obj1.encrypt(plaintext)
|
||||
obj1.IV=IV
|
||||
ciphertext2=obj1.encrypt(plaintext)
|
||||
if ciphertext1!=ciphertext2:
|
||||
die('Error in setting IV')
|
||||
|
||||
# Test keyword arguments
|
||||
obj1=ciph.new(key=password)
|
||||
obj1=ciph.new(password, mode=ciph.MODE_CBC)
|
||||
obj1=ciph.new(mode=ciph.MODE_CBC, key=password)
|
||||
obj1=ciph.new(IV=IV, mode=ciph.MODE_CBC, key=password)
|
||||
|
||||
return ciph
|
||||
|
||||
def exerciseStreamCipher(cipher, verbose):
|
||||
import string, time
|
||||
try:
|
||||
ciph = eval(cipher)
|
||||
except (NameError):
|
||||
print cipher, 'module not available'
|
||||
return None
|
||||
print cipher + ':',
|
||||
str='1' # Build 128K of test data
|
||||
for i in xrange(0, 17):
|
||||
str=str+str
|
||||
key_size = ciph.key_size or 16
|
||||
password = 'password12345678Extra text for password'[0:key_size]
|
||||
|
||||
obj1=ciph.new(password)
|
||||
obj2=ciph.new(password)
|
||||
if obj1.block_size != ciph.block_size:
|
||||
die("Module and cipher object block_size don't match")
|
||||
if obj1.key_size != ciph.key_size:
|
||||
die("Module and cipher object key_size don't match")
|
||||
|
||||
text='1234567812345678Python'
|
||||
c=obj1.encrypt(text)
|
||||
if (obj2.decrypt(c)!=text): die('Error encrypting "'+text+'"')
|
||||
text='B1FF I2 A R3A11Y |<00L D00D!!!!!'
|
||||
c=obj1.encrypt(text)
|
||||
if (obj2.decrypt(c)!=text): die('Error encrypting "'+text+'"')
|
||||
c=obj1.encrypt(text)
|
||||
if (obj2.decrypt(c)!=text): die('Error encrypting "'+text+'"')
|
||||
|
||||
start=time.time()
|
||||
s=obj1.encrypt(str)
|
||||
str=obj2.decrypt(s)
|
||||
end=time.time()
|
||||
print_timing(256, end-start, verbose)
|
||||
del obj1, obj2
|
||||
|
||||
return ciph
|
||||
|
||||
def TestStreamModules(args=['arc4', 'XOR'], verbose=1):
|
||||
import sys, string
|
||||
args=map(string.lower, args)
|
||||
|
||||
if 'arc4' in args:
|
||||
# Test ARC4 stream cipher
|
||||
arc4=exerciseStreamCipher('ARC4', verbose)
|
||||
if (arc4!=None):
|
||||
for entry in testdata.arc4:
|
||||
key,plain,cipher=entry
|
||||
key=binascii.a2b_hex(key)
|
||||
plain=binascii.a2b_hex(plain)
|
||||
cipher=binascii.a2b_hex(cipher)
|
||||
obj=arc4.new(key)
|
||||
ciphertext=obj.encrypt(plain)
|
||||
if (ciphertext!=cipher):
|
||||
die('ARC4 failed on entry '+`entry`)
|
||||
|
||||
if 'xor' in args:
|
||||
# Test XOR stream cipher
|
||||
XOR=exerciseStreamCipher('XOR', verbose)
|
||||
if (XOR!=None):
|
||||
for entry in testdata.xor:
|
||||
key,plain,cipher=entry
|
||||
key=binascii.a2b_hex(key)
|
||||
plain=binascii.a2b_hex(plain)
|
||||
cipher=binascii.a2b_hex(cipher)
|
||||
obj=XOR.new(key)
|
||||
ciphertext=obj.encrypt(plain)
|
||||
if (ciphertext!=cipher):
|
||||
die('XOR failed on entry '+`entry`)
|
||||
|
||||
|
||||
def TestBlockModules(args=['aes', 'arc2', 'des', 'blowfish', 'cast', 'des3'],
|
||||
verbose=1):
|
||||
import string
|
||||
args=map(string.lower, args)
|
||||
if 'aes' in args:
|
||||
ciph=exerciseBlockCipher('AES', verbose) # AES
|
||||
if (ciph!=None):
|
||||
if verbose: print ' Verifying against test suite...'
|
||||
for entry in testdata.aes:
|
||||
key,plain,cipher=entry
|
||||
key=binascii.a2b_hex(key)
|
||||
plain=binascii.a2b_hex(plain)
|
||||
cipher=binascii.a2b_hex(cipher)
|
||||
obj=ciph.new(key, ciph.MODE_ECB)
|
||||
ciphertext=obj.encrypt(plain)
|
||||
if (ciphertext!=cipher):
|
||||
die('AES failed on entry '+`entry`)
|
||||
for i in ciphertext:
|
||||
if verbose: print hex(ord(i)),
|
||||
if verbose: print
|
||||
|
||||
for entry in testdata.aes_modes:
|
||||
mode, key, plain, cipher, kw = entry
|
||||
key=binascii.a2b_hex(key)
|
||||
plain=binascii.a2b_hex(plain)
|
||||
cipher=binascii.a2b_hex(cipher)
|
||||
try:
|
||||
obj=ciph.new(key, mode, **kw)
|
||||
obj2=ciph.new(key, mode, **kw)
|
||||
except:
|
||||
print 'AES contruction got exception on entry '+`entry`
|
||||
raise
|
||||
try:
|
||||
ciphertext=obj.encrypt(plain)
|
||||
except:
|
||||
print 'AES encrypt got exception on entry '+`entry`
|
||||
raise
|
||||
if (ciphertext!=cipher):
|
||||
die('AES encrypt failed on entry '+`entry`)
|
||||
for i in ciphertext:
|
||||
if verbose: print hex(ord(i)),
|
||||
if verbose: print
|
||||
|
||||
plain2=obj2.decrypt(ciphertext)
|
||||
if plain2!=plain:
|
||||
die('AES decrypt failed on entry '+`entry`)
|
||||
for i in plain2:
|
||||
if verbose: print hex(ord(i)),
|
||||
if verbose: print
|
||||
|
||||
|
||||
if 'arc2' in args:
|
||||
ciph=exerciseBlockCipher('ARC2', verbose) # Alleged RC2
|
||||
if (ciph!=None):
|
||||
if verbose: print ' Verifying against test suite...'
|
||||
for entry in testdata.arc2:
|
||||
key,plain,cipher=entry
|
||||
key=binascii.a2b_hex(key)
|
||||
plain=binascii.a2b_hex(plain)
|
||||
cipher=binascii.a2b_hex(cipher)
|
||||
obj=ciph.new(key, ciph.MODE_ECB)
|
||||
ciphertext=obj.encrypt(plain)
|
||||
if (ciphertext!=cipher):
|
||||
die('ARC2 failed on entry '+`entry`)
|
||||
for i in ciphertext:
|
||||
if verbose: print hex(ord(i)),
|
||||
print
|
||||
|
||||
if 'blowfish' in args:
|
||||
ciph=exerciseBlockCipher('Blowfish',verbose)# Bruce Schneier's Blowfish cipher
|
||||
if (ciph!=None):
|
||||
if verbose: print ' Verifying against test suite...'
|
||||
for entry in testdata.blowfish:
|
||||
key,plain,cipher=entry
|
||||
key=binascii.a2b_hex(key)
|
||||
plain=binascii.a2b_hex(plain)
|
||||
cipher=binascii.a2b_hex(cipher)
|
||||
obj=ciph.new(key, ciph.MODE_ECB)
|
||||
ciphertext=obj.encrypt(plain)
|
||||
if (ciphertext!=cipher):
|
||||
die('Blowfish failed on entry '+`entry`)
|
||||
for i in ciphertext:
|
||||
if verbose: print hex(ord(i)),
|
||||
if verbose: print
|
||||
|
||||
if 'cast' in args:
|
||||
ciph=exerciseBlockCipher('CAST', verbose) # CAST-128
|
||||
if (ciph!=None):
|
||||
if verbose: print ' Verifying against test suite...'
|
||||
for entry in testdata.cast:
|
||||
key,plain,cipher=entry
|
||||
key=binascii.a2b_hex(key)
|
||||
plain=binascii.a2b_hex(plain)
|
||||
cipher=binascii.a2b_hex(cipher)
|
||||
obj=ciph.new(key, ciph.MODE_ECB)
|
||||
ciphertext=obj.encrypt(plain)
|
||||
if (ciphertext!=cipher):
|
||||
die('CAST failed on entry '+`entry`)
|
||||
for i in ciphertext:
|
||||
if verbose: print hex(ord(i)),
|
||||
if verbose: print
|
||||
|
||||
if 0:
|
||||
# The full-maintenance test; it requires 4 million encryptions,
|
||||
# and correspondingly is quite time-consuming. I've disabled
|
||||
# it; it's faster to compile block/cast.c with -DTEST and run
|
||||
# the resulting program.
|
||||
a = b = '\x01\x23\x45\x67\x12\x34\x56\x78\x23\x45\x67\x89\x34\x56\x78\x9A'
|
||||
|
||||
for i in range(0, 1000000):
|
||||
obj = cast.new(b, cast.MODE_ECB)
|
||||
a = obj.encrypt(a[:8]) + obj.encrypt(a[-8:])
|
||||
obj = cast.new(a, cast.MODE_ECB)
|
||||
b = obj.encrypt(b[:8]) + obj.encrypt(b[-8:])
|
||||
|
||||
if a!="\xEE\xA9\xD0\xA2\x49\xFD\x3B\xA6\xB3\x43\x6F\xB8\x9D\x6D\xCA\x92":
|
||||
if verbose: print 'CAST test failed: value of "a" doesn\'t match'
|
||||
if b!="\xB2\xC9\x5E\xB0\x0C\x31\xAD\x71\x80\xAC\x05\xB8\xE8\x3D\x69\x6E":
|
||||
if verbose: print 'CAST test failed: value of "b" doesn\'t match'
|
||||
|
||||
if 'des' in args:
|
||||
# Test/benchmark DES block cipher
|
||||
des=exerciseBlockCipher('DES', verbose)
|
||||
if (des!=None):
|
||||
# Various tests taken from the DES library packaged with Kerberos V4
|
||||
obj=des.new(binascii.a2b_hex('0123456789abcdef'), des.MODE_ECB)
|
||||
s=obj.encrypt('Now is t')
|
||||
if (s!=binascii.a2b_hex('3fa40e8a984d4815')):
|
||||
die('DES fails test 1')
|
||||
obj=des.new(binascii.a2b_hex('08192a3b4c5d6e7f'), des.MODE_ECB)
|
||||
s=obj.encrypt('\000\000\000\000\000\000\000\000')
|
||||
if (s!=binascii.a2b_hex('25ddac3e96176467')):
|
||||
die('DES fails test 2')
|
||||
obj=des.new(binascii.a2b_hex('0123456789abcdef'), des.MODE_CBC,
|
||||
binascii.a2b_hex('1234567890abcdef'))
|
||||
s=obj.encrypt("Now is the time for all ")
|
||||
if (s!=binascii.a2b_hex('e5c7cdde872bf27c43e934008c389c0f683788499a7c05f6')):
|
||||
die('DES fails test 3')
|
||||
obj=des.new(binascii.a2b_hex('0123456789abcdef'), des.MODE_CBC,
|
||||
binascii.a2b_hex('fedcba9876543210'))
|
||||
s=obj.encrypt("7654321 Now is the time for \000\000\000\000")
|
||||
if (s!=binascii.a2b_hex("ccd173ffab2039f4acd8aefddfd8a1eb468e91157888ba681d269397f7fe62b4")):
|
||||
die('DES fails test 4')
|
||||
del obj,s
|
||||
|
||||
# R. Rivest's test: see http://theory.lcs.mit.edu/~rivest/destest.txt
|
||||
x=binascii.a2b_hex('9474B8E8C73BCA7D')
|
||||
for i in range(0, 16):
|
||||
obj=des.new(x, des.MODE_ECB)
|
||||
if (i & 1): x=obj.decrypt(x)
|
||||
else: x=obj.encrypt(x)
|
||||
if x!=binascii.a2b_hex('1B1A2DDB4C642438'):
|
||||
die("DES fails Rivest's test")
|
||||
|
||||
if verbose: print ' Verifying against test suite...'
|
||||
for entry in testdata.des:
|
||||
key,plain,cipher=entry
|
||||
key=binascii.a2b_hex(key)
|
||||
plain=binascii.a2b_hex(plain)
|
||||
cipher=binascii.a2b_hex(cipher)
|
||||
obj=des.new(key, des.MODE_ECB)
|
||||
ciphertext=obj.encrypt(plain)
|
||||
if (ciphertext!=cipher):
|
||||
die('DES failed on entry '+`entry`)
|
||||
for entry in testdata.des_cbc:
|
||||
key, iv, plain, cipher=entry
|
||||
key, iv, cipher=binascii.a2b_hex(key),binascii.a2b_hex(iv),binascii.a2b_hex(cipher)
|
||||
obj1=des.new(key, des.MODE_CBC, iv)
|
||||
obj2=des.new(key, des.MODE_CBC, iv)
|
||||
ciphertext=obj1.encrypt(plain)
|
||||
if (ciphertext!=cipher):
|
||||
die('DES CBC mode failed on entry '+`entry`)
|
||||
|
||||
if 'des3' in args:
|
||||
ciph=exerciseBlockCipher('DES3', verbose) # Triple DES
|
||||
if (ciph!=None):
|
||||
if verbose: print ' Verifying against test suite...'
|
||||
for entry in testdata.des3:
|
||||
key,plain,cipher=entry
|
||||
key=binascii.a2b_hex(key)
|
||||
plain=binascii.a2b_hex(plain)
|
||||
cipher=binascii.a2b_hex(cipher)
|
||||
obj=ciph.new(key, ciph.MODE_ECB)
|
||||
ciphertext=obj.encrypt(plain)
|
||||
if (ciphertext!=cipher):
|
||||
die('DES3 failed on entry '+`entry`)
|
||||
for i in ciphertext:
|
||||
if verbose: print hex(ord(i)),
|
||||
if verbose: print
|
||||
for entry in testdata.des3_cbc:
|
||||
key, iv, plain, cipher=entry
|
||||
key, iv, cipher=binascii.a2b_hex(key),binascii.a2b_hex(iv),binascii.a2b_hex(cipher)
|
||||
obj1=ciph.new(key, ciph.MODE_CBC, iv)
|
||||
obj2=ciph.new(key, ciph.MODE_CBC, iv)
|
||||
ciphertext=obj1.encrypt(plain)
|
||||
if (ciphertext!=cipher):
|
||||
die('DES3 CBC mode failed on entry '+`entry`)
|
||||
|
||||
if 'idea' in args:
|
||||
ciph=exerciseBlockCipher('IDEA', verbose) # IDEA block cipher
|
||||
if (ciph!=None):
|
||||
if verbose: print ' Verifying against test suite...'
|
||||
for entry in testdata.idea:
|
||||
key,plain,cipher=entry
|
||||
key=binascii.a2b_hex(key)
|
||||
plain=binascii.a2b_hex(plain)
|
||||
cipher=binascii.a2b_hex(cipher)
|
||||
obj=ciph.new(key, ciph.MODE_ECB)
|
||||
ciphertext=obj.encrypt(plain)
|
||||
if (ciphertext!=cipher):
|
||||
die('IDEA failed on entry '+`entry`)
|
||||
|
||||
if 'rc5' in args:
|
||||
# Ronald Rivest's RC5 algorithm
|
||||
ciph=exerciseBlockCipher('RC5', verbose)
|
||||
if (ciph!=None):
|
||||
if verbose: print ' Verifying against test suite...'
|
||||
for entry in testdata.rc5:
|
||||
key,plain,cipher=entry
|
||||
key=binascii.a2b_hex(key)
|
||||
plain=binascii.a2b_hex(plain)
|
||||
cipher=binascii.a2b_hex(cipher)
|
||||
obj=ciph.new(key[4:], ciph.MODE_ECB,
|
||||
version =ord(key[0]),
|
||||
word_size=ord(key[1]),
|
||||
rounds =ord(key[2]) )
|
||||
ciphertext=obj.encrypt(plain)
|
||||
if (ciphertext!=cipher):
|
||||
die('RC5 failed on entry '+`entry`)
|
||||
for i in ciphertext:
|
||||
if verbose: print hex(ord(i)),
|
||||
if verbose: print
|
||||
|
||||
|
||||
|
@ -1,24 +0,0 @@
|
||||
|
||||
import time
|
||||
from allmydata.Crypto.Util import number
|
||||
|
||||
# Test of prime-generation speed
|
||||
|
||||
# This randfunc is deterministic, so we should always find the same primes.
|
||||
chars = ''.join(map(chr, range(255, 0, -1)))
|
||||
def randfunc (N):
|
||||
s = ''
|
||||
while len(s)<N:
|
||||
s += chars
|
||||
return s[:N]
|
||||
|
||||
def main ():
|
||||
for i in range(128, 2049, 128):
|
||||
s = time.time()
|
||||
N = number.getPrime(i, randfunc)
|
||||
e = time.time()
|
||||
N = str(N)
|
||||
print '%5i' % i, '%-7.03fsec' % (e-s), N[:10] + '...' + N[-10:]
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -1,25 +0,0 @@
|
||||
|
||||
"""Python Cryptography Toolkit
|
||||
|
||||
A collection of cryptographic modules implementing various algorithms
|
||||
and protocols.
|
||||
|
||||
Subpackages:
|
||||
Crypto.Cipher Secret-key encryption algorithms (AES, DES, ARC4)
|
||||
Crypto.Hash Hashing algorithms (MD5, SHA, HMAC)
|
||||
Crypto.Protocol Cryptographic protocols (Chaffing, all-or-nothing
|
||||
transform). This package does not contain any
|
||||
network protocols.
|
||||
Crypto.PublicKey Public-key encryption and signature algorithms
|
||||
(RSA, DSA)
|
||||
Crypto.Util Various useful modules and functions (long-to-string
|
||||
conversion, random number generation, number
|
||||
theoretic functions)
|
||||
"""
|
||||
|
||||
__all__ = ['Cipher', 'Hash', 'Protocol', 'PublicKey', 'Util']
|
||||
|
||||
__version__ = '2.0.1'
|
||||
__revision__ = "$Id: __init__.py,v 1.12 2005/06/14 01:20:22 akuchling Exp $"
|
||||
|
||||
|
@ -1,26 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
#
|
||||
# Benchmark script for the Python Cryptography Toolkit.
|
||||
#
|
||||
|
||||
__revision__ = "$Id: test.py,v 1.7 2002/07/11 14:31:19 akuchling Exp $"
|
||||
|
||||
import os, sys
|
||||
|
||||
|
||||
# Add the build directory to the front of sys.path
|
||||
from distutils.util import get_platform
|
||||
s = "build/lib.%s-%.3s" % (get_platform(), sys.version)
|
||||
s = os.path.join(os.getcwd(), s)
|
||||
sys.path.insert(0, s)
|
||||
s = os.path.join(os.getcwd(), 'test')
|
||||
sys.path.insert(0, s)
|
||||
|
||||
from allmydata.Crypto.Util import bench
|
||||
|
||||
args = sys.argv[1:]
|
||||
quiet = "--quiet" in args
|
||||
if quiet: args.remove('--quiet')
|
||||
|
||||
bench.bench_aes_ctr()
|
@ -1,12 +0,0 @@
|
||||
pycrypto for Debian
|
||||
-------------------
|
||||
|
||||
The debian pythonX.Y-crypto packages contain the Python cryptographic
|
||||
toolkit compiled for Python X.Y. I have removed the following
|
||||
algorithms from the upstream source code due to patent/copyright
|
||||
issues:
|
||||
|
||||
* IDEA - patent issues
|
||||
* RC5 - patent issues
|
||||
* RIPEMD - unclarified copyright
|
||||
|
@ -1,137 +0,0 @@
|
||||
python-amdcrypto (2.0.1.allmydata2) unstable; urgency=low
|
||||
|
||||
* Pulled in zooko's CTR-mode patches, including the one that handles
|
||||
encryption chunks that are not multiples of the cipher's blocksize.
|
||||
* Changed the package name to avoid confusion with the
|
||||
not-entirely-compatible normal python-crypto package.
|
||||
* Changed this into a native package, since the changes relative to the
|
||||
best remaining upstream source (2.0.1 from
|
||||
http://www.amk.ca/python/code/crypto) are kinda weird (add debian/*,
|
||||
remove non-free algorithms, add zooko's patch). This source tarball is
|
||||
kept in a darcs repository in hanford:~warner/trees-pycrypto/trunk.
|
||||
|
||||
-- Brian Warner <warner@allmydata.com> Mon, 5 Jun 2006 16:45:58 -0700
|
||||
|
||||
python-crypto (2.0.1+dfsg1-1) unstable; urgency=low
|
||||
|
||||
* Acknowlegde NMUs (closes: #318055, #318012).
|
||||
* Packaged new upstream version (closes: #325517).
|
||||
- 2.0.1 includes fix for AMD64, presumingly also closes: #297516.
|
||||
|
||||
-- Andreas Rottmann <rotty@debian.org> Tue, 4 Oct 2005 00:10:40 +0200
|
||||
|
||||
python-crypto (2.0+dp1-2.3) unstable; urgency=low
|
||||
|
||||
* NMU.
|
||||
* Add python2.4-crypto package, drop python2.1 and python2.2 packages
|
||||
(closes: #313349).
|
||||
|
||||
-- Matthias Klose <doko@debian.org> Mon, 29 Aug 2005 07:18:38 +0000
|
||||
|
||||
python-crypto (2.0+dp1-2.2) unstable; urgency=low
|
||||
|
||||
* NMU to fix build failures on some architectures
|
||||
* Remove -O3 gcc option on m68k architecture to fix FTBFS due to an
|
||||
internal compiler error
|
||||
* Standards version 3.6.2 (no changes required)
|
||||
* Relax the versioned build dependency of libgmp3-dev to 4.1.4-8
|
||||
instead of -9. Some architectures only have -8 at this point
|
||||
which is sufficient.
|
||||
|
||||
-- Bastian Kleineidam <calvin@debian.org> Fri, 12 Aug 2005 11:04:21 +0200
|
||||
|
||||
python-crypto (2.0+dp1-2.1) unstable; urgency=low
|
||||
|
||||
* NMU to make package installable again
|
||||
* Added missing build dependency on (versioned) libgmp3-dev, otherwise
|
||||
the _fastmath module won't be compiled.
|
||||
* Recompile against libgmp3c2 (Closes: #318055)
|
||||
|
||||
-- Bastian Kleineidam <calvin@debian.org> Tue, 9 Aug 2005 10:54:41 +0200
|
||||
|
||||
python-crypto (2.0+dp1-2) unstable; urgency=medium
|
||||
|
||||
* Added missing build-dependency on tetex-bin and tetex-extra (closes:
|
||||
#288602).
|
||||
|
||||
-- Andreas Rottmann <rotty@debian.org> Tue, 4 Jan 2005 17:47:27 +0100
|
||||
|
||||
python-crypto (2.0+dp1-1) unstable; urgency=medium
|
||||
|
||||
* Again remove problematic code from orig tarball, which the NMU did
|
||||
miss (not to mention that the orig tarball from the NMU wasn't
|
||||
pristine and contained .pyc files). Urgency medium, so sarge won't end
|
||||
up with problematic code.
|
||||
* Include the manual in binary packages (closes: #273622).
|
||||
* Switch to CDBS.
|
||||
* Lowercase description synopsis, as suggested by lintian/developer's
|
||||
reference.
|
||||
* Advertice the newly-included (since 2.0) SHA256 module in the
|
||||
description.
|
||||
|
||||
-- Andreas Rottmann <rotty@debian.org> Sat, 1 Jan 2005 14:47:12 +0100
|
||||
|
||||
python-crypto (2.0-1) unstable; urgency=medium
|
||||
|
||||
* NMU.
|
||||
* New upstream version.
|
||||
|
||||
-- Matthias Klose <doko@debian.org> Tue, 17 Aug 2004 23:44:24 +0200
|
||||
|
||||
python-crypto (1.9a6+dp2-1) unstable; urgency=low
|
||||
|
||||
* Transitioned to Python 2.3.
|
||||
* Removed accidential junk form .orig.tar.gz.
|
||||
|
||||
-- Andreas Rottmann <rotty@debian.org> Sat, 9 Aug 2003 12:41:23 +0200
|
||||
|
||||
python-crypto (1.9a6+dp1-2) unstable; urgency=low
|
||||
|
||||
* Fixed Section (python instead of interpreters).
|
||||
|
||||
-- Andreas Rottmann <rotty@debian.org> Sun, 20 Jul 2003 15:21:37 +0200
|
||||
|
||||
python-crypto (1.9a6+dp1-1) unstable; urgency=low
|
||||
|
||||
* New upstream release.
|
||||
* Bump Standards-Version to 3.6.0 (no changes).
|
||||
|
||||
-- Andreas Rottmann <rotty@debian.org> Sun, 13 Jul 2003 18:26:54 +0200
|
||||
|
||||
python-crypto (1.9a4+dp1-4) unstable; urgency=low
|
||||
|
||||
* Use dh_python.
|
||||
+ Build-depend on debhelper >= 4.1.29.
|
||||
+ Build-depend on python.
|
||||
* Bump Standards-Version to 3.5.8.
|
||||
|
||||
-- Andreas Rottmann <rotty@debian.org> Thu, 20 Feb 2003 14:55:12 +0100
|
||||
|
||||
python-crypto (1.9a4+dp1-3) unstable; urgency=low
|
||||
|
||||
* Cipher/__init__.py: Remove 'RC5' and 'IDEA' from __all__.
|
||||
|
||||
-- Andreas Rottmann <rotty@debian.org> Fri, 14 Feb 2003 01:10:26 +0100
|
||||
|
||||
python-crypto (1.9a4+dp1-2) unstable; urgency=low
|
||||
|
||||
* debian/control: Added python2.x dependencies to binary packages.
|
||||
* debian/control: Fixed 'Cryptpgraphic' typo (closes: #162884).
|
||||
|
||||
-- Andreas Rottmann <rotty@debian.org> Thu, 7 Nov 2002 22:05:27 +0100
|
||||
|
||||
python-crypto (1.9a4+dp1-1) unstable; urgency=low
|
||||
|
||||
* Removed problematic algorithms from source code.
|
||||
+ Added README.Debian with details.
|
||||
+ Updated package descriptions.
|
||||
* Include docs in all pythonX.Y-crypto packages.
|
||||
|
||||
-- Andreas Rottmann <rotty@debian.org> Wed, 11 Sep 2002 13:15:45 +0200
|
||||
|
||||
python-crypto (1.9a4-1) unstable; urgency=low
|
||||
|
||||
* Initial Release (closes: #159717)
|
||||
|
||||
-- Andreas Rottmann <rotty@debian.org> Thu, 5 Sep 2002 14:53:33 +0200
|
||||
|
@ -1 +0,0 @@
|
||||
4
|
@ -1,60 +0,0 @@
|
||||
Source: python-amdcrypto
|
||||
Section: python
|
||||
Priority: optional
|
||||
Maintainer: Andreas Rottmann <rotty@debian.org>
|
||||
Build-Depends: cdbs, debhelper (>= 4.2), python, python2.3-dev, python2.4-dev, ed, tetex-bin, tetex-extra, libgmp3-dev (>= 4.1.4-10)
|
||||
Standards-Version: 3.6.2
|
||||
|
||||
Package: python-amdcrypto
|
||||
Architecture: any
|
||||
Depends: ${python:Depends}
|
||||
Conflicts: python-crypto
|
||||
Provides: python-crypto
|
||||
Description: cryptographic algorithms and protocols for Python
|
||||
A collection of cryptographic algorithms and protocols, implemented
|
||||
for use from Python. Among the contents of the package:
|
||||
.
|
||||
* Hash functions: MD2, MD4.
|
||||
* Block encryption algorithms: AES, ARC2, Blowfish, CAST, DES, Triple-DES.
|
||||
* Stream encryption algorithms: ARC4, simple XOR.
|
||||
* Public-key algorithms: RSA, DSA, ElGamal, qNEW.
|
||||
* Protocols: All-or-nothing transforms, chaffing/winnowing.
|
||||
* Miscellaneous: RFC1751 module for converting 128-key keys
|
||||
into a set of English words, primality testing.
|
||||
.
|
||||
This is an empty dummy package that always depends on a package built
|
||||
for Debian's default Python version.
|
||||
|
||||
Package: python2.3-amdcrypto
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends}, python2.3
|
||||
Conflicts: python2.3-crypto
|
||||
Provides: python2.3-crypto
|
||||
Description: cryptographic algorithms and protocols for Python
|
||||
A collection of cryptographic algorithms and protocols, implemented
|
||||
for use from Python. Among the contents of the package:
|
||||
.
|
||||
* Hash functions: MD2, MD4, SHA256.
|
||||
* Block encryption algorithms: AES, ARC2, Blowfish, CAST, DES, Triple-DES.
|
||||
* Stream encryption algorithms: ARC4, simple XOR.
|
||||
* Public-key algorithms: RSA, DSA, ElGamal, qNEW.
|
||||
* Protocols: All-or-nothing transforms, chaffing/winnowing.
|
||||
* Miscellaneous: RFC1751 module for converting 128-key keys
|
||||
into a set of English words, primality testing.
|
||||
|
||||
Package: python2.4-amdcrypto
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends}, python2.4
|
||||
Conflicts: python2.4-crypto
|
||||
Provides: python2.4-crypto
|
||||
Description: cryptographic algorithms and protocols for Python
|
||||
A collection of cryptographic algorithms and protocols, implemented
|
||||
for use from Python. Among the contents of the package:
|
||||
.
|
||||
* Hash functions: MD2, MD4.
|
||||
* Block encryption algorithms: AES, ARC2, Blowfish, CAST, DES, Triple-DES.
|
||||
* Stream encryption algorithms: ARC4, simple XOR.
|
||||
* Public-key algorithms: RSA, DSA, ElGamal, qNEW.
|
||||
* Protocols: All-or-nothing transforms, chaffing/winnowing.
|
||||
* Miscellaneous: RFC1751 module for converting 128-key keys
|
||||
into a set of English words, primality testing.
|
@ -1,20 +0,0 @@
|
||||
This package was debianized by Andreas Rottmann <rotty@debian.org> on
|
||||
Thu, 5 Sep 2002 14:53:33 +0200.
|
||||
|
||||
It was downloaded from http://www.amk.ca/python/code/crypto.html
|
||||
|
||||
Upstream Author: A.M. Kuchling <akuchlin@mems-exchange.org>
|
||||
|
||||
Copyright:
|
||||
|
||||
===================================================================
|
||||
Distribute and use freely; there are no restrictions on further
|
||||
dissemination and usage except those imposed by the laws of your
|
||||
country of residence. This software is provided "as is" without
|
||||
warranty of fitness for use or suitability for any purpose, express
|
||||
or implied. Use at your own risk or not at all.
|
||||
===================================================================
|
||||
|
||||
Incorporating the code into commercial products is permitted; you do
|
||||
not have to make source available or contribute your changes back
|
||||
(though that would be nice).
|
@ -1,2 +0,0 @@
|
||||
usr/bin
|
||||
usr/sbin
|
@ -1,17 +0,0 @@
|
||||
#! /bin/sh
|
||||
#
|
||||
# This script is used to mangle things like /usr/local/bin/python into
|
||||
# something more in line with Debian's Python policy.
|
||||
|
||||
set -e
|
||||
|
||||
CMD=$1
|
||||
DIR=$2
|
||||
|
||||
grep -E -l -r '/usr/local(/bin)?/python' "$DIR" |
|
||||
while read f; do
|
||||
printf ",s:/usr/local\\\\(/bin\\\\)\\\\?/python:$CMD:g\nw\n" | ed -s "$f"
|
||||
if [ "$(head -c2 $f)" = "#!" ]; then
|
||||
chmod 755 "$f"
|
||||
fi
|
||||
done
|
@ -1,4 +0,0 @@
|
||||
README
|
||||
TODO
|
||||
debian/README.Debian
|
||||
Doc/pycrypt.ps
|
@ -1,4 +0,0 @@
|
||||
README
|
||||
TODO
|
||||
debian/README.Debian
|
||||
Doc/pycrypt.ps
|
@ -1,17 +0,0 @@
|
||||
#!/usr/bin/make -f
|
||||
|
||||
include /usr/share/cdbs/1/rules/buildcore.mk
|
||||
include /usr/share/cdbs/1/rules/debhelper.mk
|
||||
include /usr/share/cdbs/1/class/python-distutils.mk
|
||||
|
||||
MKHOWTO = /usr/lib/python2.3/doc/tools/mkhowto
|
||||
|
||||
common-build-arch::
|
||||
cd Doc && $(MKHOWTO) --ps
|
||||
|
||||
$(patsubst %,binary-post-install/%,$(DEB_PYTHON_REAL_LIB_PACKAGES))::
|
||||
sh -e debian/pathmangle.sh /usr/bin/$(shell echo $(cdbs_curpkg) | sed 's,-crypto$$,,') debian/$(cdbs_curpkg)
|
||||
|
||||
clean::
|
||||
rm -rf build
|
||||
rm -f Doc/*.ps
|
@ -1,191 +0,0 @@
|
||||
#! /usr/bin/env python
|
||||
|
||||
from distutils import core
|
||||
from distutils.core import Extension
|
||||
from distutils.command.build_ext import build_ext
|
||||
import os, sys
|
||||
|
||||
if sys.version[0:1] == '1':
|
||||
raise RuntimeError, ("The Python Cryptography Toolkit requires "
|
||||
"Python 2.x to build.")
|
||||
|
||||
debug_build_kw = {}
|
||||
|
||||
DEBUG_BUILD=False
|
||||
# DEBUG_BUILD=True
|
||||
if DEBUG_BUILD:
|
||||
debug_build_kw.update({
|
||||
'extra_compile_args': ['-O0', '-g',],
|
||||
'extra_link_args': ['-g',],
|
||||
'undef_macros': ['NDEBUG',], })
|
||||
|
||||
if sys.platform == 'win32':
|
||||
HTONS_LIBS = ['ws2_32']
|
||||
plat_ext = [
|
||||
Extension("allmydata.Crypto.Util.winrandom",
|
||||
libraries = HTONS_LIBS + ['advapi32'],
|
||||
include_dirs=['src/'],
|
||||
extra_compile_args=['-O0 -g',],
|
||||
extra_link_args=['-g',],
|
||||
undef_macros=['NDEBUG',],
|
||||
sources=["src/winrand.c"],
|
||||
**debug_build_kw)
|
||||
]
|
||||
else:
|
||||
HTONS_LIBS = []
|
||||
plat_ext = []
|
||||
|
||||
# Functions for finding libraries and files, copied from Python's setup.py.
|
||||
|
||||
def find_file(filename, std_dirs, paths):
|
||||
"""Searches for the directory where a given file is located,
|
||||
and returns a possibly-empty list of additional directories, or None
|
||||
if the file couldn't be found at all.
|
||||
|
||||
'filename' is the name of a file, such as readline.h or libcrypto.a.
|
||||
'std_dirs' is the list of standard system directories; if the
|
||||
file is found in one of them, no additional directives are needed.
|
||||
'paths' is a list of additional locations to check; if the file is
|
||||
found in one of them, the resulting list will contain the directory.
|
||||
"""
|
||||
|
||||
# Check the standard locations
|
||||
for dir in std_dirs:
|
||||
f = os.path.join(dir, filename)
|
||||
if os.path.exists(f): return []
|
||||
|
||||
# Check the additional directories
|
||||
for dir in paths:
|
||||
f = os.path.join(dir, filename)
|
||||
if os.path.exists(f):
|
||||
return [dir]
|
||||
|
||||
# Not found anywhere
|
||||
return None
|
||||
|
||||
def find_library_file(compiler, libname, std_dirs, paths):
|
||||
filename = compiler.library_filename(libname, lib_type='shared')
|
||||
result = find_file(filename, std_dirs, paths)
|
||||
if result is not None: return result
|
||||
|
||||
filename = compiler.library_filename(libname, lib_type='static')
|
||||
result = find_file(filename, std_dirs, paths)
|
||||
return result
|
||||
|
||||
|
||||
def cc_remove_option (compiler, option):
|
||||
"""
|
||||
Remove option from Unix-style compiler.
|
||||
"""
|
||||
for optlist in (compiler.compiler, compiler.compiler_so):
|
||||
if option in optlist:
|
||||
optlist.remove(option)
|
||||
|
||||
|
||||
class PCTBuildExt (build_ext):
|
||||
def build_extensions(self):
|
||||
self.extensions += [
|
||||
# Hash functions
|
||||
Extension("allmydata.Crypto.Hash.MD4",
|
||||
include_dirs=['src/'],
|
||||
sources=["src/MD4.c"],
|
||||
**debug_build_kw),
|
||||
Extension("allmydata.Crypto.Hash.SHA256",
|
||||
include_dirs=['src/'],
|
||||
sources=["src/SHA256.c"],
|
||||
**debug_build_kw),
|
||||
|
||||
# Block encryption algorithms
|
||||
Extension("allmydata.Crypto.Cipher.AES",
|
||||
include_dirs=['src/'],
|
||||
sources=["src/AES.c"],
|
||||
**debug_build_kw),
|
||||
Extension("allmydata.Crypto.Cipher.ARC2",
|
||||
include_dirs=['src/'],
|
||||
sources=["src/ARC2.c"],
|
||||
**debug_build_kw),
|
||||
Extension("allmydata.Crypto.Cipher.Blowfish",
|
||||
include_dirs=['src/'],
|
||||
sources=["src/Blowfish.c"],
|
||||
**debug_build_kw),
|
||||
Extension("allmydata.Crypto.Cipher.CAST",
|
||||
include_dirs=['src/'],
|
||||
sources=["src/CAST.c"],
|
||||
**debug_build_kw),
|
||||
Extension("allmydata.Crypto.Cipher.DES",
|
||||
include_dirs=['src/'],
|
||||
sources=["src/DES.c"],
|
||||
**debug_build_kw),
|
||||
Extension("allmydata.Crypto.Cipher.DES3",
|
||||
include_dirs=['src/'],
|
||||
sources=["src/DES3.c"],
|
||||
**debug_build_kw),
|
||||
|
||||
# Stream ciphers
|
||||
Extension("allmydata.Crypto.Cipher.ARC4",
|
||||
include_dirs=['src/'],
|
||||
sources=["src/ARC4.c"],
|
||||
**debug_build_kw),
|
||||
Extension("allmydata.Crypto.Cipher.XOR",
|
||||
include_dirs=['src/'],
|
||||
sources=["src/XOR.c"],
|
||||
**debug_build_kw),
|
||||
]
|
||||
|
||||
# Detect which modules should be compiled
|
||||
self.detect_modules()
|
||||
if self.compiler.compiler_type == 'unix':
|
||||
if os.uname()[4] == 'm68k':
|
||||
# work around ICE on m68k machines in gcc 4.0.1
|
||||
cc_remove_option(self.compiler, "-O3")
|
||||
build_ext.build_extensions(self)
|
||||
|
||||
def detect_modules (self):
|
||||
lib_dirs = self.compiler.library_dirs + ['/lib', '/usr/lib']
|
||||
inc_dirs = self.compiler.include_dirs + ['/usr/include']
|
||||
exts = []
|
||||
if (self.compiler.find_library_file(lib_dirs, 'gmp')):
|
||||
exts.append(Extension("allmydata.Crypto.PublicKey._fastmath",
|
||||
include_dirs=['src/'],
|
||||
libraries=['gmp'],
|
||||
sources=["src/_fastmath.c"]))
|
||||
self.extensions += exts
|
||||
|
||||
|
||||
kw = {'name':"pycrypto",
|
||||
'version':"2.0.1",
|
||||
'description':"Cryptographic modules for Python.",
|
||||
'author':"A.M. Kuchling",
|
||||
'author_email':"amk@amk.ca",
|
||||
'url':"http://www.amk.ca/python/code/crypto",
|
||||
|
||||
'cmdclass' : {'build_ext':PCTBuildExt},
|
||||
'packages' : ["allmydata.Crypto", "allmydata.Crypto.Hash", "allmydata.Crypto.Cipher", "allmydata.Crypto.Util",
|
||||
"allmydata.Crypto.Protocol", "allmydata.Crypto.PublicKey"],
|
||||
'package_dir' : { "allmydata.Crypto":"." },
|
||||
# One module is defined here, because build_ext won't be
|
||||
# called unless there's at least one extension module defined.
|
||||
'ext_modules':[Extension("allmydata.Crypto.Hash.MD2",
|
||||
include_dirs=['src/'],
|
||||
sources=["src/MD2.c"],
|
||||
**debug_build_kw)]
|
||||
}
|
||||
|
||||
# If we're running Python 2.3, add extra information
|
||||
if hasattr(core, 'setup_keywords'):
|
||||
if 'classifiers' in core.setup_keywords:
|
||||
kw['classifiers'] = [
|
||||
'Development Status :: 4 - Beta',
|
||||
'License :: Public Domain',
|
||||
'Intended Audience :: Developers',
|
||||
'Operating System :: Unix',
|
||||
'Operating System :: Microsoft :: Windows',
|
||||
'Operating System :: MacOS :: MacOS X',
|
||||
'Topic :: Security :: Cryptography',
|
||||
]
|
||||
if 'download_url' in core.setup_keywords:
|
||||
kw['download_url'] = ('http://www.amk.ca/files/python/crypto/'
|
||||
'%s-%s.tar.gz' % (kw['name'], kw['version']) )
|
||||
|
||||
core.setup(**kw)
|
||||
|
@ -1,185 +0,0 @@
|
||||
|
||||
/*
|
||||
* rc2.c : Source code for the RC2 block cipher
|
||||
*
|
||||
* Part of the Python Cryptography Toolkit
|
||||
*
|
||||
* Distribute and use freely; there are no restrictions on further
|
||||
* dissemination and usage except those imposed by the laws of your
|
||||
* country of residence.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define MODULE_NAME ARC2
|
||||
#define BLOCK_SIZE 8
|
||||
#define KEY_SIZE 0
|
||||
|
||||
typedef unsigned int U32;
|
||||
typedef unsigned short U16;
|
||||
typedef unsigned char U8;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
U16 xkey[64];
|
||||
} block_state;
|
||||
|
||||
static void
|
||||
block_encrypt(block_state *self, U8 *in, U8 *out)
|
||||
{
|
||||
U16 x76, x54, x32, x10;
|
||||
int i;
|
||||
|
||||
x76 = (in[7] << 8) + in[6];
|
||||
x54 = (in[5] << 8) + in[4];
|
||||
x32 = (in[3] << 8) + in[2];
|
||||
x10 = (in[1] << 8) + in[0];
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
x10 += (x32 & ~x76) + (x54 & x76) + self->xkey[4*i+0];
|
||||
x10 = (x10 << 1) + (x10 >> 15 & 1);
|
||||
|
||||
x32 += (x54 & ~x10) + (x76 & x10) + self->xkey[4*i+1];
|
||||
x32 = (x32 << 2) + (x32 >> 14 & 3);
|
||||
|
||||
x54 += (x76 & ~x32) + (x10 & x32) + self->xkey[4*i+2];
|
||||
x54 = (x54 << 3) + (x54 >> 13 & 7);
|
||||
|
||||
x76 += (x10 & ~x54) + (x32 & x54) + self->xkey[4*i+3];
|
||||
x76 = (x76 << 5) + (x76 >> 11 & 31);
|
||||
|
||||
if (i == 4 || i == 10) {
|
||||
x10 += self->xkey[x76 & 63];
|
||||
x32 += self->xkey[x10 & 63];
|
||||
x54 += self->xkey[x32 & 63];
|
||||
x76 += self->xkey[x54 & 63];
|
||||
}
|
||||
}
|
||||
|
||||
out[0] = (U8)x10;
|
||||
out[1] = (U8)(x10 >> 8);
|
||||
out[2] = (U8)x32;
|
||||
out[3] = (U8)(x32 >> 8);
|
||||
out[4] = (U8)x54;
|
||||
out[5] = (U8)(x54 >> 8);
|
||||
out[6] = (U8)x76;
|
||||
out[7] = (U8)(x76 >> 8);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
block_decrypt(block_state *self, U8 *in, U8 *out)
|
||||
{
|
||||
U16 x76, x54, x32, x10;
|
||||
int i;
|
||||
|
||||
x76 = (in[7] << 8) + in[6];
|
||||
x54 = (in[5] << 8) + in[4];
|
||||
x32 = (in[3] << 8) + in[2];
|
||||
x10 = (in[1] << 8) + in[0];
|
||||
|
||||
i = 15;
|
||||
do {
|
||||
x76 &= 65535;
|
||||
x76 = (x76 << 11) + (x76 >> 5);
|
||||
x76 -= (x10 & ~x54) + (x32 & x54) + self->xkey[4*i+3];
|
||||
|
||||
x54 &= 65535;
|
||||
x54 = (x54 << 13) + (x54 >> 3);
|
||||
x54 -= (x76 & ~x32) + (x10 & x32) + self->xkey[4*i+2];
|
||||
|
||||
x32 &= 65535;
|
||||
x32 = (x32 << 14) + (x32 >> 2);
|
||||
x32 -= (x54 & ~x10) + (x76 & x10) + self->xkey[4*i+1];
|
||||
|
||||
x10 &= 65535;
|
||||
x10 = (x10 << 15) + (x10 >> 1);
|
||||
x10 -= (x32 & ~x76) + (x54 & x76) + self->xkey[4*i+0];
|
||||
|
||||
if (i == 5 || i == 11) {
|
||||
x76 -= self->xkey[x54 & 63];
|
||||
x54 -= self->xkey[x32 & 63];
|
||||
x32 -= self->xkey[x10 & 63];
|
||||
x10 -= self->xkey[x76 & 63];
|
||||
}
|
||||
} while (i--);
|
||||
|
||||
out[0] = (U8)x10;
|
||||
out[1] = (U8)(x10 >> 8);
|
||||
out[2] = (U8)x32;
|
||||
out[3] = (U8)(x32 >> 8);
|
||||
out[4] = (U8)x54;
|
||||
out[5] = (U8)(x54 >> 8);
|
||||
out[6] = (U8)x76;
|
||||
out[7] = (U8)(x76 >> 8);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
block_init(block_state *self, U8 *key, int keylength)
|
||||
{
|
||||
U8 x;
|
||||
U16 i;
|
||||
/* 256-entry permutation table, probably derived somehow from pi */
|
||||
static const U8 permute[256] = {
|
||||
217,120,249,196, 25,221,181,237, 40,233,253,121, 74,160,216,157,
|
||||
198,126, 55,131, 43,118, 83,142, 98, 76,100,136, 68,139,251,162,
|
||||
23,154, 89,245,135,179, 79, 19, 97, 69,109,141, 9,129,125, 50,
|
||||
189,143, 64,235,134,183,123, 11,240,149, 33, 34, 92,107, 78,130,
|
||||
84,214,101,147,206, 96,178, 28,115, 86,192, 20,167,140,241,220,
|
||||
18,117,202, 31, 59,190,228,209, 66, 61,212, 48,163, 60,182, 38,
|
||||
111,191, 14,218, 70,105, 7, 87, 39,242, 29,155,188,148, 67, 3,
|
||||
248, 17,199,246,144,239, 62,231, 6,195,213, 47,200,102, 30,215,
|
||||
8,232,234,222,128, 82,238,247,132,170,114,172, 53, 77,106, 42,
|
||||
150, 26,210,113, 90, 21, 73,116, 75,159,208, 94, 4, 24,164,236,
|
||||
194,224, 65,110, 15, 81,203,204, 36,145,175, 80,161,244,112, 57,
|
||||
153,124, 58,133, 35,184,180,122,252, 2, 54, 91, 37, 85,151, 49,
|
||||
45, 93,250,152,227,138,146,174, 5,223, 41, 16,103,108,186,201,
|
||||
211, 0,230,207,225,158,168, 44, 99, 22, 1, 63, 88,226,137,169,
|
||||
13, 56, 52, 27,171, 51,255,176,187, 72, 12, 95,185,177,205, 46,
|
||||
197,243,219, 71,229,165,156,119, 10,166, 32,104,254,127,193,173
|
||||
};
|
||||
|
||||
/* The "bits" value may be some sort of export control weakening.
|
||||
We'll hardwire it to 1024. */
|
||||
#define bits 1024
|
||||
|
||||
memcpy(self->xkey, key, keylength);
|
||||
|
||||
/* Phase 1: Expand input key to 128 bytes */
|
||||
if (keylength < 128) {
|
||||
i = 0;
|
||||
x = ((U8 *)self->xkey)[keylength-1];
|
||||
do {
|
||||
x = permute[(x + ((U8 *)self->xkey)[i++]) & 255];
|
||||
((U8 *)self->xkey)[keylength++] = x;
|
||||
} while (keylength < 128);
|
||||
}
|
||||
|
||||
/* Phase 2 - reduce effective key size to "bits" */
|
||||
keylength = (bits+7) >> 3;
|
||||
i = 128-keylength;
|
||||
x = permute[((U8 *)self->xkey)[i] & (255 >>
|
||||
(7 &
|
||||
((bits %8 ) ? 8-(bits%8): 0))
|
||||
)];
|
||||
((U8 *)self->xkey)[i] = x;
|
||||
|
||||
while (i--) {
|
||||
x = permute[ x ^ ((U8 *)self->xkey)[i+keylength] ];
|
||||
((U8 *)self->xkey)[i] = x;
|
||||
}
|
||||
|
||||
/* Phase 3 - copy to self->xkey in little-endian order */
|
||||
i = 63;
|
||||
do {
|
||||
self->xkey[i] = ((U8 *)self->xkey)[2*i] +
|
||||
(((U8 *)self->xkey)[2*i+1] << 8);
|
||||
} while (i--);
|
||||
}
|
||||
|
||||
#undef bits
|
||||
|
||||
#include "block_template.c"
|
@ -1,72 +0,0 @@
|
||||
|
||||
/*
|
||||
* arc4.c : Implementation for the Alleged-RC4 stream cipher
|
||||
*
|
||||
* Part of the Python Cryptography Toolkit
|
||||
*
|
||||
* Distribute and use freely; there are no restrictions on further
|
||||
* dissemination and usage except those imposed by the laws of your
|
||||
* country of residence.
|
||||
*
|
||||
*/
|
||||
|
||||
#define MODULE_NAME ARC4
|
||||
#define BLOCK_SIZE 1
|
||||
#define KEY_SIZE 0
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char state[256];
|
||||
unsigned char x,y;
|
||||
} stream_state;
|
||||
|
||||
/* Encryption and decryption are symmetric */
|
||||
#define stream_decrypt stream_encrypt
|
||||
|
||||
static void stream_encrypt(stream_state *self, unsigned char *block,
|
||||
int len)
|
||||
{
|
||||
register int i, x=self->x, y=self->y;
|
||||
|
||||
for (i=0; i<len; i++)
|
||||
{
|
||||
x = (x + 1) % 256;
|
||||
y = (y + self->state[x]) % 256;
|
||||
{
|
||||
register int t; /* Exchange state[x] and state[y] */
|
||||
t = self->state[x];
|
||||
self->state[x] = self->state[y];
|
||||
self->state[y] = t;
|
||||
}
|
||||
{
|
||||
register int xorIndex; /* XOR the data with the stream data */
|
||||
xorIndex=(self->state[x]+self->state[y]) % 256;
|
||||
block[i] ^= self->state[xorIndex];
|
||||
}
|
||||
}
|
||||
self->x=x;
|
||||
self->y=y;
|
||||
}
|
||||
|
||||
|
||||
static void stream_init(stream_state *self, unsigned char *key, int keylen)
|
||||
{
|
||||
register int i, index1, index2;
|
||||
|
||||
for(i=0; i<256; i++) self->state[i]=i;
|
||||
self->x=0; self->y=0;
|
||||
index1=0; index2=0;
|
||||
for(i=0; i<256; i++)
|
||||
{
|
||||
register int t;
|
||||
index2 = ( key[index1] + self->state[i] + index2) % 256;
|
||||
t = self->state[i];
|
||||
self->state[i] = self->state[index2];
|
||||
self->state[index2] = t;
|
||||
index1 = (index1 + 1) % keylen;
|
||||
}
|
||||
}
|
||||
|
||||
#include "stream_template.c"
|
||||
|
||||
|
@ -1,499 +0,0 @@
|
||||
|
||||
/*
|
||||
* blowfish.c : Source code for the Blowfish block cipher
|
||||
*
|
||||
* Part of the Python Cryptography Toolkit
|
||||
*
|
||||
* Distribute and use freely; there are no restrictions on further
|
||||
* dissemination and usage except those imposed by the laws of your
|
||||
* country of residence.
|
||||
*
|
||||
*/
|
||||
|
||||
/*************************************************************************/
|
||||
/* File: bf.c
|
||||
Blowfish cipher by Bruce Schneier,
|
||||
Code by Bryan Olson, based partly on Schneier's.
|
||||
*/
|
||||
|
||||
#include "Python.h"
|
||||
|
||||
#define MODULE_NAME Blowfish
|
||||
#define BLOCK_SIZE 8
|
||||
#define KEY_SIZE 0
|
||||
|
||||
/* Define IntU32 to be an unsigned in 32 bits long */
|
||||
typedef unsigned int IntU32 ;
|
||||
typedef unsigned char IntU8 ;
|
||||
#define NROUNDS 16
|
||||
|
||||
|
||||
|
||||
/* Define IntP to be an integer which
|
||||
is the same size as a pointer. */
|
||||
typedef unsigned long IntP ;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
IntU32 p[2][NROUNDS+2],
|
||||
sbox[4][256] ;
|
||||
} BFkey_type ;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BFkey_type bfkey;
|
||||
} block_state;
|
||||
|
||||
/* File bfinit.h
|
||||
Data to initialize P and S in BlowFish.
|
||||
*/
|
||||
|
||||
static IntU32 p_init[NROUNDS+2] =
|
||||
{
|
||||
608135816UL, 2242054355UL, 320440878UL, 57701188UL,
|
||||
2752067618UL, 698298832UL, 137296536UL, 3964562569UL,
|
||||
1160258022UL, 953160567UL, 3193202383UL, 887688300UL,
|
||||
3232508343UL, 3380367581UL, 1065670069UL, 3041331479UL,
|
||||
2450970073UL, 2306472731UL
|
||||
} ;
|
||||
|
||||
static IntU32 s_init[4][256] = {
|
||||
{3509652390UL, 2564797868UL, 805139163UL, 3491422135UL,
|
||||
3101798381UL, 1780907670UL, 3128725573UL, 4046225305UL,
|
||||
614570311UL, 3012652279UL, 134345442UL, 2240740374UL,
|
||||
1667834072UL, 1901547113UL, 2757295779UL, 4103290238UL,
|
||||
227898511UL, 1921955416UL, 1904987480UL, 2182433518UL,
|
||||
2069144605UL, 3260701109UL, 2620446009UL, 720527379UL,
|
||||
3318853667UL, 677414384UL, 3393288472UL, 3101374703UL,
|
||||
2390351024UL, 1614419982UL, 1822297739UL, 2954791486UL,
|
||||
3608508353UL, 3174124327UL, 2024746970UL, 1432378464UL,
|
||||
3864339955UL, 2857741204UL, 1464375394UL, 1676153920UL,
|
||||
1439316330UL, 715854006UL, 3033291828UL, 289532110UL,
|
||||
2706671279UL, 2087905683UL, 3018724369UL, 1668267050UL,
|
||||
732546397UL, 1947742710UL, 3462151702UL, 2609353502UL,
|
||||
2950085171UL, 1814351708UL, 2050118529UL, 680887927UL,
|
||||
999245976UL, 1800124847UL, 3300911131UL, 1713906067UL,
|
||||
1641548236UL, 4213287313UL, 1216130144UL, 1575780402UL,
|
||||
4018429277UL, 3917837745UL, 3693486850UL, 3949271944UL,
|
||||
596196993UL, 3549867205UL, 258830323UL, 2213823033UL,
|
||||
772490370UL, 2760122372UL, 1774776394UL, 2652871518UL,
|
||||
566650946UL, 4142492826UL, 1728879713UL, 2882767088UL,
|
||||
1783734482UL, 3629395816UL, 2517608232UL, 2874225571UL,
|
||||
1861159788UL, 326777828UL, 3124490320UL, 2130389656UL,
|
||||
2716951837UL, 967770486UL, 1724537150UL, 2185432712UL,
|
||||
2364442137UL, 1164943284UL, 2105845187UL, 998989502UL,
|
||||
3765401048UL, 2244026483UL, 1075463327UL, 1455516326UL,
|
||||
1322494562UL, 910128902UL, 469688178UL, 1117454909UL,
|
||||
936433444UL, 3490320968UL, 3675253459UL, 1240580251UL,
|
||||
122909385UL, 2157517691UL, 634681816UL, 4142456567UL,
|
||||
3825094682UL, 3061402683UL, 2540495037UL, 79693498UL,
|
||||
3249098678UL, 1084186820UL, 1583128258UL, 426386531UL,
|
||||
1761308591UL, 1047286709UL, 322548459UL, 995290223UL,
|
||||
1845252383UL, 2603652396UL, 3431023940UL, 2942221577UL,
|
||||
3202600964UL, 3727903485UL, 1712269319UL, 422464435UL,
|
||||
3234572375UL, 1170764815UL, 3523960633UL, 3117677531UL,
|
||||
1434042557UL, 442511882UL, 3600875718UL, 1076654713UL,
|
||||
1738483198UL, 4213154764UL, 2393238008UL, 3677496056UL,
|
||||
1014306527UL, 4251020053UL, 793779912UL, 2902807211UL,
|
||||
842905082UL, 4246964064UL, 1395751752UL, 1040244610UL,
|
||||
2656851899UL, 3396308128UL, 445077038UL, 3742853595UL,
|
||||
3577915638UL, 679411651UL, 2892444358UL, 2354009459UL,
|
||||
1767581616UL, 3150600392UL, 3791627101UL, 3102740896UL,
|
||||
284835224UL, 4246832056UL, 1258075500UL, 768725851UL,
|
||||
2589189241UL, 3069724005UL, 3532540348UL, 1274779536UL,
|
||||
3789419226UL, 2764799539UL, 1660621633UL, 3471099624UL,
|
||||
4011903706UL, 913787905UL, 3497959166UL, 737222580UL,
|
||||
2514213453UL, 2928710040UL, 3937242737UL, 1804850592UL,
|
||||
3499020752UL, 2949064160UL, 2386320175UL, 2390070455UL,
|
||||
2415321851UL, 4061277028UL, 2290661394UL, 2416832540UL,
|
||||
1336762016UL, 1754252060UL, 3520065937UL, 3014181293UL,
|
||||
791618072UL, 3188594551UL, 3933548030UL, 2332172193UL,
|
||||
3852520463UL, 3043980520UL, 413987798UL, 3465142937UL,
|
||||
3030929376UL, 4245938359UL, 2093235073UL, 3534596313UL,
|
||||
375366246UL, 2157278981UL, 2479649556UL, 555357303UL,
|
||||
3870105701UL, 2008414854UL, 3344188149UL, 4221384143UL,
|
||||
3956125452UL, 2067696032UL, 3594591187UL, 2921233993UL,
|
||||
2428461UL, 544322398UL, 577241275UL, 1471733935UL,
|
||||
610547355UL, 4027169054UL, 1432588573UL, 1507829418UL,
|
||||
2025931657UL, 3646575487UL, 545086370UL, 48609733UL,
|
||||
2200306550UL, 1653985193UL, 298326376UL, 1316178497UL,
|
||||
3007786442UL, 2064951626UL, 458293330UL, 2589141269UL,
|
||||
3591329599UL, 3164325604UL, 727753846UL, 2179363840UL,
|
||||
146436021UL, 1461446943UL, 4069977195UL, 705550613UL,
|
||||
3059967265UL, 3887724982UL, 4281599278UL, 3313849956UL,
|
||||
1404054877UL, 2845806497UL, 146425753UL, 1854211946UL},
|
||||
|
||||
{ 1266315497UL, 3048417604UL, 3681880366UL, 3289982499UL,
|
||||
2909710000UL, 1235738493UL, 2632868024UL, 2414719590UL,
|
||||
3970600049UL, 1771706367UL, 1449415276UL, 3266420449UL,
|
||||
422970021UL, 1963543593UL, 2690192192UL, 3826793022UL,
|
||||
1062508698UL, 1531092325UL, 1804592342UL, 2583117782UL,
|
||||
2714934279UL, 4024971509UL, 1294809318UL, 4028980673UL,
|
||||
1289560198UL, 2221992742UL, 1669523910UL, 35572830UL,
|
||||
157838143UL, 1052438473UL, 1016535060UL, 1802137761UL,
|
||||
1753167236UL, 1386275462UL, 3080475397UL, 2857371447UL,
|
||||
1040679964UL, 2145300060UL, 2390574316UL, 1461121720UL,
|
||||
2956646967UL, 4031777805UL, 4028374788UL, 33600511UL,
|
||||
2920084762UL, 1018524850UL, 629373528UL, 3691585981UL,
|
||||
3515945977UL, 2091462646UL, 2486323059UL, 586499841UL,
|
||||
988145025UL, 935516892UL, 3367335476UL, 2599673255UL,
|
||||
2839830854UL, 265290510UL, 3972581182UL, 2759138881UL,
|
||||
3795373465UL, 1005194799UL, 847297441UL, 406762289UL,
|
||||
1314163512UL, 1332590856UL, 1866599683UL, 4127851711UL,
|
||||
750260880UL, 613907577UL, 1450815602UL, 3165620655UL,
|
||||
3734664991UL, 3650291728UL, 3012275730UL, 3704569646UL,
|
||||
1427272223UL, 778793252UL, 1343938022UL, 2676280711UL,
|
||||
2052605720UL, 1946737175UL, 3164576444UL, 3914038668UL,
|
||||
3967478842UL, 3682934266UL, 1661551462UL, 3294938066UL,
|
||||
4011595847UL, 840292616UL, 3712170807UL, 616741398UL,
|
||||
312560963UL, 711312465UL, 1351876610UL, 322626781UL,
|
||||
1910503582UL, 271666773UL, 2175563734UL, 1594956187UL,
|
||||
70604529UL, 3617834859UL, 1007753275UL, 1495573769UL,
|
||||
4069517037UL, 2549218298UL, 2663038764UL, 504708206UL,
|
||||
2263041392UL, 3941167025UL, 2249088522UL, 1514023603UL,
|
||||
1998579484UL, 1312622330UL, 694541497UL, 2582060303UL,
|
||||
2151582166UL, 1382467621UL, 776784248UL, 2618340202UL,
|
||||
3323268794UL, 2497899128UL, 2784771155UL, 503983604UL,
|
||||
4076293799UL, 907881277UL, 423175695UL, 432175456UL,
|
||||
1378068232UL, 4145222326UL, 3954048622UL, 3938656102UL,
|
||||
3820766613UL, 2793130115UL, 2977904593UL, 26017576UL,
|
||||
3274890735UL, 3194772133UL, 1700274565UL, 1756076034UL,
|
||||
4006520079UL, 3677328699UL, 720338349UL, 1533947780UL,
|
||||
354530856UL, 688349552UL, 3973924725UL, 1637815568UL,
|
||||
332179504UL, 3949051286UL, 53804574UL, 2852348879UL,
|
||||
3044236432UL, 1282449977UL, 3583942155UL, 3416972820UL,
|
||||
4006381244UL, 1617046695UL, 2628476075UL, 3002303598UL,
|
||||
1686838959UL, 431878346UL, 2686675385UL, 1700445008UL,
|
||||
1080580658UL, 1009431731UL, 832498133UL, 3223435511UL,
|
||||
2605976345UL, 2271191193UL, 2516031870UL, 1648197032UL,
|
||||
4164389018UL, 2548247927UL, 300782431UL, 375919233UL,
|
||||
238389289UL, 3353747414UL, 2531188641UL, 2019080857UL,
|
||||
1475708069UL, 455242339UL, 2609103871UL, 448939670UL,
|
||||
3451063019UL, 1395535956UL, 2413381860UL, 1841049896UL,
|
||||
1491858159UL, 885456874UL, 4264095073UL, 4001119347UL,
|
||||
1565136089UL, 3898914787UL, 1108368660UL, 540939232UL,
|
||||
1173283510UL, 2745871338UL, 3681308437UL, 4207628240UL,
|
||||
3343053890UL, 4016749493UL, 1699691293UL, 1103962373UL,
|
||||
3625875870UL, 2256883143UL, 3830138730UL, 1031889488UL,
|
||||
3479347698UL, 1535977030UL, 4236805024UL, 3251091107UL,
|
||||
2132092099UL, 1774941330UL, 1199868427UL, 1452454533UL,
|
||||
157007616UL, 2904115357UL, 342012276UL, 595725824UL,
|
||||
1480756522UL, 206960106UL, 497939518UL, 591360097UL,
|
||||
863170706UL, 2375253569UL, 3596610801UL, 1814182875UL,
|
||||
2094937945UL, 3421402208UL, 1082520231UL, 3463918190UL,
|
||||
2785509508UL, 435703966UL, 3908032597UL, 1641649973UL,
|
||||
2842273706UL, 3305899714UL, 1510255612UL, 2148256476UL,
|
||||
2655287854UL, 3276092548UL, 4258621189UL, 236887753UL,
|
||||
3681803219UL, 274041037UL, 1734335097UL, 3815195456UL,
|
||||
3317970021UL, 1899903192UL, 1026095262UL, 4050517792UL,
|
||||
356393447UL, 2410691914UL, 3873677099UL, 3682840055UL},
|
||||
|
||||
{ 3913112168UL, 2491498743UL, 4132185628UL, 2489919796UL,
|
||||
1091903735UL, 1979897079UL, 3170134830UL, 3567386728UL,
|
||||
3557303409UL, 857797738UL, 1136121015UL, 1342202287UL,
|
||||
507115054UL, 2535736646UL, 337727348UL, 3213592640UL,
|
||||
1301675037UL, 2528481711UL, 1895095763UL, 1721773893UL,
|
||||
3216771564UL, 62756741UL, 2142006736UL, 835421444UL,
|
||||
2531993523UL, 1442658625UL, 3659876326UL, 2882144922UL,
|
||||
676362277UL, 1392781812UL, 170690266UL, 3921047035UL,
|
||||
1759253602UL, 3611846912UL, 1745797284UL, 664899054UL,
|
||||
1329594018UL, 3901205900UL, 3045908486UL, 2062866102UL,
|
||||
2865634940UL, 3543621612UL, 3464012697UL, 1080764994UL,
|
||||
553557557UL, 3656615353UL, 3996768171UL, 991055499UL,
|
||||
499776247UL, 1265440854UL, 648242737UL, 3940784050UL,
|
||||
980351604UL, 3713745714UL, 1749149687UL, 3396870395UL,
|
||||
4211799374UL, 3640570775UL, 1161844396UL, 3125318951UL,
|
||||
1431517754UL, 545492359UL, 4268468663UL, 3499529547UL,
|
||||
1437099964UL, 2702547544UL, 3433638243UL, 2581715763UL,
|
||||
2787789398UL, 1060185593UL, 1593081372UL, 2418618748UL,
|
||||
4260947970UL, 69676912UL, 2159744348UL, 86519011UL,
|
||||
2512459080UL, 3838209314UL, 1220612927UL, 3339683548UL,
|
||||
133810670UL, 1090789135UL, 1078426020UL, 1569222167UL,
|
||||
845107691UL, 3583754449UL, 4072456591UL, 1091646820UL,
|
||||
628848692UL, 1613405280UL, 3757631651UL, 526609435UL,
|
||||
236106946UL, 48312990UL, 2942717905UL, 3402727701UL,
|
||||
1797494240UL, 859738849UL, 992217954UL, 4005476642UL,
|
||||
2243076622UL, 3870952857UL, 3732016268UL, 765654824UL,
|
||||
3490871365UL, 2511836413UL, 1685915746UL, 3888969200UL,
|
||||
1414112111UL, 2273134842UL, 3281911079UL, 4080962846UL,
|
||||
172450625UL, 2569994100UL, 980381355UL, 4109958455UL,
|
||||
2819808352UL, 2716589560UL, 2568741196UL, 3681446669UL,
|
||||
3329971472UL, 1835478071UL, 660984891UL, 3704678404UL,
|
||||
4045999559UL, 3422617507UL, 3040415634UL, 1762651403UL,
|
||||
1719377915UL, 3470491036UL, 2693910283UL, 3642056355UL,
|
||||
3138596744UL, 1364962596UL, 2073328063UL, 1983633131UL,
|
||||
926494387UL, 3423689081UL, 2150032023UL, 4096667949UL,
|
||||
1749200295UL, 3328846651UL, 309677260UL, 2016342300UL,
|
||||
1779581495UL, 3079819751UL, 111262694UL, 1274766160UL,
|
||||
443224088UL, 298511866UL, 1025883608UL, 3806446537UL,
|
||||
1145181785UL, 168956806UL, 3641502830UL, 3584813610UL,
|
||||
1689216846UL, 3666258015UL, 3200248200UL, 1692713982UL,
|
||||
2646376535UL, 4042768518UL, 1618508792UL, 1610833997UL,
|
||||
3523052358UL, 4130873264UL, 2001055236UL, 3610705100UL,
|
||||
2202168115UL, 4028541809UL, 2961195399UL, 1006657119UL,
|
||||
2006996926UL, 3186142756UL, 1430667929UL, 3210227297UL,
|
||||
1314452623UL, 4074634658UL, 4101304120UL, 2273951170UL,
|
||||
1399257539UL, 3367210612UL, 3027628629UL, 1190975929UL,
|
||||
2062231137UL, 2333990788UL, 2221543033UL, 2438960610UL,
|
||||
1181637006UL, 548689776UL, 2362791313UL, 3372408396UL,
|
||||
3104550113UL, 3145860560UL, 296247880UL, 1970579870UL,
|
||||
3078560182UL, 3769228297UL, 1714227617UL, 3291629107UL,
|
||||
3898220290UL, 166772364UL, 1251581989UL, 493813264UL,
|
||||
448347421UL, 195405023UL, 2709975567UL, 677966185UL,
|
||||
3703036547UL, 1463355134UL, 2715995803UL, 1338867538UL,
|
||||
1343315457UL, 2802222074UL, 2684532164UL, 233230375UL,
|
||||
2599980071UL, 2000651841UL, 3277868038UL, 1638401717UL,
|
||||
4028070440UL, 3237316320UL, 6314154UL, 819756386UL,
|
||||
300326615UL, 590932579UL, 1405279636UL, 3267499572UL,
|
||||
3150704214UL, 2428286686UL, 3959192993UL, 3461946742UL,
|
||||
1862657033UL, 1266418056UL, 963775037UL, 2089974820UL,
|
||||
2263052895UL, 1917689273UL, 448879540UL, 3550394620UL,
|
||||
3981727096UL, 150775221UL, 3627908307UL, 1303187396UL,
|
||||
508620638UL, 2975983352UL, 2726630617UL, 1817252668UL,
|
||||
1876281319UL, 1457606340UL, 908771278UL, 3720792119UL,
|
||||
3617206836UL, 2455994898UL, 1729034894UL, 1080033504UL},
|
||||
|
||||
{ 976866871UL, 3556439503UL, 2881648439UL, 1522871579UL,
|
||||
1555064734UL, 1336096578UL, 3548522304UL, 2579274686UL,
|
||||
3574697629UL, 3205460757UL, 3593280638UL, 3338716283UL,
|
||||
3079412587UL, 564236357UL, 2993598910UL, 1781952180UL,
|
||||
1464380207UL, 3163844217UL, 3332601554UL, 1699332808UL,
|
||||
1393555694UL, 1183702653UL, 3581086237UL, 1288719814UL,
|
||||
691649499UL, 2847557200UL, 2895455976UL, 3193889540UL,
|
||||
2717570544UL, 1781354906UL, 1676643554UL, 2592534050UL,
|
||||
3230253752UL, 1126444790UL, 2770207658UL, 2633158820UL,
|
||||
2210423226UL, 2615765581UL, 2414155088UL, 3127139286UL,
|
||||
673620729UL, 2805611233UL, 1269405062UL, 4015350505UL,
|
||||
3341807571UL, 4149409754UL, 1057255273UL, 2012875353UL,
|
||||
2162469141UL, 2276492801UL, 2601117357UL, 993977747UL,
|
||||
3918593370UL, 2654263191UL, 753973209UL, 36408145UL,
|
||||
2530585658UL, 25011837UL, 3520020182UL, 2088578344UL,
|
||||
530523599UL, 2918365339UL, 1524020338UL, 1518925132UL,
|
||||
3760827505UL, 3759777254UL, 1202760957UL, 3985898139UL,
|
||||
3906192525UL, 674977740UL, 4174734889UL, 2031300136UL,
|
||||
2019492241UL, 3983892565UL, 4153806404UL, 3822280332UL,
|
||||
352677332UL, 2297720250UL, 60907813UL, 90501309UL,
|
||||
3286998549UL, 1016092578UL, 2535922412UL, 2839152426UL,
|
||||
457141659UL, 509813237UL, 4120667899UL, 652014361UL,
|
||||
1966332200UL, 2975202805UL, 55981186UL, 2327461051UL,
|
||||
676427537UL, 3255491064UL, 2882294119UL, 3433927263UL,
|
||||
1307055953UL, 942726286UL, 933058658UL, 2468411793UL,
|
||||
3933900994UL, 4215176142UL, 1361170020UL, 2001714738UL,
|
||||
2830558078UL, 3274259782UL, 1222529897UL, 1679025792UL,
|
||||
2729314320UL, 3714953764UL, 1770335741UL, 151462246UL,
|
||||
3013232138UL, 1682292957UL, 1483529935UL, 471910574UL,
|
||||
1539241949UL, 458788160UL, 3436315007UL, 1807016891UL,
|
||||
3718408830UL, 978976581UL, 1043663428UL, 3165965781UL,
|
||||
1927990952UL, 4200891579UL, 2372276910UL, 3208408903UL,
|
||||
3533431907UL, 1412390302UL, 2931980059UL, 4132332400UL,
|
||||
1947078029UL, 3881505623UL, 4168226417UL, 2941484381UL,
|
||||
1077988104UL, 1320477388UL, 886195818UL, 18198404UL,
|
||||
3786409000UL, 2509781533UL, 112762804UL, 3463356488UL,
|
||||
1866414978UL, 891333506UL, 18488651UL, 661792760UL,
|
||||
1628790961UL, 3885187036UL, 3141171499UL, 876946877UL,
|
||||
2693282273UL, 1372485963UL, 791857591UL, 2686433993UL,
|
||||
3759982718UL, 3167212022UL, 3472953795UL, 2716379847UL,
|
||||
445679433UL, 3561995674UL, 3504004811UL, 3574258232UL,
|
||||
54117162UL, 3331405415UL, 2381918588UL, 3769707343UL,
|
||||
4154350007UL, 1140177722UL, 4074052095UL, 668550556UL,
|
||||
3214352940UL, 367459370UL, 261225585UL, 2610173221UL,
|
||||
4209349473UL, 3468074219UL, 3265815641UL, 314222801UL,
|
||||
3066103646UL, 3808782860UL, 282218597UL, 3406013506UL,
|
||||
3773591054UL, 379116347UL, 1285071038UL, 846784868UL,
|
||||
2669647154UL, 3771962079UL, 3550491691UL, 2305946142UL,
|
||||
453669953UL, 1268987020UL, 3317592352UL, 3279303384UL,
|
||||
3744833421UL, 2610507566UL, 3859509063UL, 266596637UL,
|
||||
3847019092UL, 517658769UL, 3462560207UL, 3443424879UL,
|
||||
370717030UL, 4247526661UL, 2224018117UL, 4143653529UL,
|
||||
4112773975UL, 2788324899UL, 2477274417UL, 1456262402UL,
|
||||
2901442914UL, 1517677493UL, 1846949527UL, 2295493580UL,
|
||||
3734397586UL, 2176403920UL, 1280348187UL, 1908823572UL,
|
||||
3871786941UL, 846861322UL, 1172426758UL, 3287448474UL,
|
||||
3383383037UL, 1655181056UL, 3139813346UL, 901632758UL,
|
||||
1897031941UL, 2986607138UL, 3066810236UL, 3447102507UL,
|
||||
1393639104UL, 373351379UL, 950779232UL, 625454576UL,
|
||||
3124240540UL, 4148612726UL, 2007998917UL, 544563296UL,
|
||||
2244738638UL, 2330496472UL, 2058025392UL, 1291430526UL,
|
||||
424198748UL, 50039436UL, 29584100UL, 3605783033UL,
|
||||
2429876329UL, 2791104160UL, 1057563949UL, 3255363231UL,
|
||||
3075367218UL, 3463963227UL, 1469046755UL, 985887462UL}
|
||||
} ;
|
||||
|
||||
/* sLb(s,n) allows us to subsript s by byte offsets, which
|
||||
allows us to avoid a subscript scaling.
|
||||
*/
|
||||
#define sub(s,n) *((IntU32 *)((IntP)s+(n)))
|
||||
|
||||
/* Below is one BlowFish round including the F function
|
||||
*/
|
||||
#define bf_round(l,r,n) \
|
||||
l ^= P[n]; \
|
||||
r ^= ( (sub(S[0],l>>22 & 0x3fc) + sub(S[1],l>>14 & 0x3fc)) \
|
||||
^ sub(S[2],l>>6 & 0x3fc) ) +S[3][l & 0xff]
|
||||
|
||||
|
||||
|
||||
/* This function requires the block to be two 32 bit integers, in
|
||||
whatever endian form the machine uses. On little endian machines
|
||||
use crypt_8bytes() on user data. make_bfkey should call crypt_block
|
||||
on either endian machine. Pass direction 0 to encrypt, 1 to decrypt.
|
||||
*/
|
||||
static void crypt_block(IntU32 block[2], BFkey_type *bfkey, int direction)
|
||||
{
|
||||
register IntU32 left, right,
|
||||
(*S)[256],
|
||||
*P ;
|
||||
|
||||
left = block[0] ; right = block[1] ;
|
||||
|
||||
S = bfkey->sbox ;
|
||||
P = bfkey->p[direction] ;
|
||||
|
||||
bf_round( left, right, 0 ) ; bf_round( right, left, 1 ) ;
|
||||
bf_round( left, right, 2 ) ; bf_round( right, left, 3 ) ;
|
||||
bf_round( left, right, 4 ) ; bf_round( right, left, 5 ) ;
|
||||
bf_round( left, right, 6 ) ; bf_round( right, left, 7 ) ;
|
||||
bf_round( left, right, 8 ) ; bf_round( right, left, 9 ) ;
|
||||
bf_round( left, right, 10 ) ; bf_round( right, left, 11 ) ;
|
||||
bf_round( left, right, 12 ) ; bf_round( right, left, 13 ) ;
|
||||
bf_round( left, right, 14 ) ; bf_round( right, left, 15 ) ;
|
||||
|
||||
left = left ^ P[NROUNDS] ;
|
||||
right = right ^ P[NROUNDS+1] ;
|
||||
block[0] = right ;
|
||||
block[1] = left ;
|
||||
}
|
||||
|
||||
/* The following should be allignment and endian independent.
|
||||
I have not tested it on a little-endian machine.
|
||||
It takes the input block from source, and puts the output
|
||||
in dest. They can be the same. It takes the same direction
|
||||
parameter as crypt_block().
|
||||
*/
|
||||
static void crypt_8bytes(IntU8 *source, IntU8 *dest, BFkey_type *bfkey,
|
||||
int direction)
|
||||
{
|
||||
IntU32 block[2] ;
|
||||
|
||||
block[0] = source[3] | source[2]<<8 | source[1]<<16 | source[0]<<24 ;
|
||||
block[1] = source[7] | source[6]<<8 | source[5]<<16 | source[4]<<24 ;
|
||||
|
||||
crypt_block( block, bfkey, direction ) ;
|
||||
|
||||
dest[0]= block[0]>>24 ;
|
||||
dest[1]= block[0]>>16 & 0xff ;
|
||||
dest[2]= block[0]>>8 & 0xff ;
|
||||
dest[3]= block[0] & 0xff ;
|
||||
dest[4]= block[1]>>24 ;
|
||||
dest[5]= block[1]>>16 & 0xff ;
|
||||
dest[6]= block[1]>> 8 & 0xff ;
|
||||
dest[7]= block[1] & 0xff ;
|
||||
}
|
||||
|
||||
/* make_bfkey() takes the address of the key data as a char*,
|
||||
and the length of the key in bytes. It generates and returns
|
||||
a pointer to an object of BFkey_type, which can be passed
|
||||
to the crypt functions. It does some simple testing of the
|
||||
init data and crypt routine, and returns 0 on error.
|
||||
*/
|
||||
static void make_bfkey(unsigned char *key_string, int keylength,
|
||||
BFkey_type *bfkey)
|
||||
{
|
||||
int i, j, k ;
|
||||
IntU32 dspace[2],
|
||||
checksum=0 ;
|
||||
|
||||
/* Copy constant initial data to P vector */
|
||||
for( i=0 ; i<NROUNDS+2 ; ++i )
|
||||
{
|
||||
bfkey->p[0][i] = p_init[i] ;
|
||||
bfkey->p[1][NROUNDS+1-i] = p_init[i] ;
|
||||
checksum = (checksum<<1 | checksum>>31)+p_init[i] ;
|
||||
}
|
||||
|
||||
/* Copy constant initial data to sboxes */
|
||||
for( i=0 ; i<4 ; ++i )
|
||||
for( j=0 ; j<256 ; ++j )
|
||||
{
|
||||
bfkey->sbox[i][j] = s_init[i][j] ;
|
||||
checksum = ((checksum*13)<<11 | (checksum*13)>>21)
|
||||
+ s_init[i][j] ;
|
||||
}
|
||||
|
||||
/* Test init data. */
|
||||
if( checksum != 0x55861a61 )
|
||||
{
|
||||
PyErr_SetString(PyExc_SystemError,
|
||||
"Blowfish: Bad initialization data");
|
||||
return;
|
||||
}
|
||||
|
||||
dspace[0] = 0 ;
|
||||
dspace[1] = 0 ;
|
||||
|
||||
/* Test the crypt_block() routine. */
|
||||
for( i=0 ; i<10 ; ++i )
|
||||
crypt_block( dspace, bfkey, 0 ) ;
|
||||
checksum = dspace[0] ;
|
||||
for( i=0 ; i<10 ; ++i )
|
||||
crypt_block( dspace, bfkey, 1 ) ;
|
||||
if( (checksum!=0xaafe4ebd) || dspace[0] || dspace[1] )
|
||||
{
|
||||
PyErr_SetString(PyExc_SystemError,
|
||||
"Blowfish: Error in crypt_block routine");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Xor key string into encryption key vector */
|
||||
j = 0 ;
|
||||
for (i=0 ; i<NROUNDS+2 ; ++i)
|
||||
{
|
||||
IntU32 data;
|
||||
data = 0 ;
|
||||
for (k=0 ; k<4 ; ++k )
|
||||
data = (data << 8) | key_string[j++ % keylength];
|
||||
(bfkey->p)[0][i] ^= data;
|
||||
}
|
||||
|
||||
|
||||
for (i = 0 ; i<NROUNDS+2 ; i+=2)
|
||||
{
|
||||
crypt_block( dspace, bfkey, 0 ) ;
|
||||
bfkey->p[0][i] = dspace[0] ;
|
||||
bfkey->p[1][NROUNDS+1-i] = dspace[0] ;
|
||||
bfkey->p[0][i+1] = dspace[1] ;
|
||||
bfkey->p[1][NROUNDS-i] = dspace[1] ;
|
||||
}
|
||||
|
||||
for ( i=0 ; i<4 ; ++i )
|
||||
for ( j=0 ; j<256 ; j+=2 )
|
||||
{
|
||||
crypt_block( dspace, bfkey, 0 ) ;
|
||||
bfkey->sbox[i][j] = dspace[0] ;
|
||||
bfkey->sbox[i][j+1] = dspace[1] ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
block_encrypt(block_state *self, unsigned char *in, unsigned char *out)
|
||||
{
|
||||
crypt_8bytes(in, out, &(self->bfkey), 0);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
block_decrypt(block_state *self, unsigned char *in, unsigned char *out)
|
||||
{
|
||||
crypt_8bytes(in, out, &(self->bfkey), 1);
|
||||
}
|
||||
|
||||
static void
|
||||
block_init(block_state *self, unsigned char *key, int keylength)
|
||||
{
|
||||
make_bfkey(key, keylength, &(self->bfkey));
|
||||
}
|
||||
|
||||
#include "block_template.c"
|
@ -1,436 +0,0 @@
|
||||
/*
|
||||
cast.c -- implementation of CAST-128 (aka CAST5) as described in RFC2144
|
||||
|
||||
compile -DTEST to include main() which performs the tests
|
||||
specified in RFC2144
|
||||
|
||||
Written by Wim Lewis <wiml@hhhh.org> based entirely on RFC2144. This code
|
||||
is in the public domain. Consult your local laws for possible restrictions
|
||||
on use, distribution, and import/export. RFC2144 states that this
|
||||
algorithm "is available worldwide on a royalty-free basis for commercial
|
||||
and non-commercial uses".
|
||||
|
||||
This code is a pretty straightforward transliteration of the RFC into C.
|
||||
It has not been optimized much at all: byte-order-independent arithmetic
|
||||
operations are used where order-dependent pointer ops or unions might be
|
||||
faster; the code could be rearranged to give the optimizer a better
|
||||
chance to speed things up; etc.
|
||||
|
||||
This code requires a vaguely ANSI-ish compiler.
|
||||
|
||||
Tested with gcc 2.5.8 on i486, i586, i686, hp pa-risc, mc68040, sparc;
|
||||
also with gcc 2.7.2 and (with minor changes) native Sun compiler on sparc
|
||||
|
||||
History:
|
||||
21 Jul 1997: wiml : first working version & Python module
|
||||
*/
|
||||
|
||||
#include "Python.h"
|
||||
|
||||
#define MODULE_NAME CAST
|
||||
#define BLOCK_SIZE 8
|
||||
#define KEY_SIZE 0
|
||||
|
||||
/* adjust these according to your compiler/platform. On some machines
|
||||
uint32 will have to be a long. It's OK if uint32 is more than 32 bits. */
|
||||
typedef unsigned int uint32;
|
||||
typedef unsigned char uint8;
|
||||
|
||||
/* this struct probably belongs in cast.h */
|
||||
typedef struct {
|
||||
/* masking and rotate keys */
|
||||
uint32 Km[16];
|
||||
uint8 Kr[16];
|
||||
/* number of rounds (depends on original unpadded keylength) */
|
||||
int rounds;
|
||||
} block_state;
|
||||
|
||||
/* these are the eight 32*256 S-boxes */
|
||||
#include "cast5.c"
|
||||
|
||||
/* fetch a uint32 from an array of uint8s (with a given offset) */
|
||||
#define fetch(ptr, base) (((((( ptr[base]<< 8 ) | ptr[base+1] )<< 8 ) | ptr[base+2] )<< 8 ) | ptr[base+3])
|
||||
|
||||
/* this is the round function f(D, Km, Kr) */
|
||||
static uint32 castfunc(uint32 D, uint32 Kmi, uint8 Kri, int type)
|
||||
{
|
||||
uint32 I, f;
|
||||
short Ia, Ib, Ic, Id;
|
||||
|
||||
switch(type) {
|
||||
case 0:
|
||||
I = (Kmi + D) ;
|
||||
break;
|
||||
case 1:
|
||||
I = (Kmi ^ D) ;
|
||||
break;
|
||||
default:
|
||||
case 2:
|
||||
I = (Kmi - D) ;
|
||||
break;
|
||||
}
|
||||
|
||||
I &= 0xFFFFFFFF;
|
||||
I = ( I << Kri ) | ( I >> ( 32-Kri ) );
|
||||
Ia = ( I >> 24 ) & 0xFF;
|
||||
Ib = ( I >> 16 ) & 0xFF;
|
||||
Ic = ( I >> 8 ) & 0xFF;
|
||||
Id = ( I ) & 0xFF;
|
||||
|
||||
switch(type) {
|
||||
case 0:
|
||||
f = ((S1[Ia] ^ S2[Ib]) - S3[Ic]) + S4[Id];
|
||||
break;
|
||||
case 1:
|
||||
f = ((S1[Ia] - S2[Ib]) + S3[Ic]) ^ S4[Id];
|
||||
break;
|
||||
default:
|
||||
case 2:
|
||||
f = ((S1[Ia] + S2[Ib]) ^ S3[Ic]) - S4[Id];
|
||||
break;
|
||||
}
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
/* encrypts/decrypts one block of data according to the key schedule
|
||||
pointed to by `key'. Encrypts if decrypt=0, otherwise decrypts. */
|
||||
static void castcrypt(block_state *key, uint8 *block, int decrypt)
|
||||
{
|
||||
uint32 L, R, tmp, f;
|
||||
uint32 Kmi;
|
||||
uint8 Kri;
|
||||
short functype, round;
|
||||
|
||||
L = fetch(block, 0);
|
||||
R = fetch(block, 4);
|
||||
|
||||
/* printf("L0 = %08x R0 = %08x\n", L, R); */
|
||||
|
||||
for(round = 0; round < key->rounds; round ++) {
|
||||
|
||||
if (!decrypt) {
|
||||
Kmi = key->Km[round];
|
||||
Kri = key->Kr[round];
|
||||
functype = round % 3;
|
||||
} else {
|
||||
Kmi = key->Km[(key->rounds) - round - 1];
|
||||
Kri = key->Kr[(key->rounds) - round - 1];
|
||||
functype = (((key->rounds) - round - 1) % 3);
|
||||
}
|
||||
|
||||
f = castfunc(R, Kmi, Kri, functype);
|
||||
|
||||
tmp = L;
|
||||
L = R;
|
||||
R = tmp ^ f;
|
||||
|
||||
/* printf("L%d = %08x R%d = %08x\n", round+1, L, round+1, R); */
|
||||
}
|
||||
|
||||
block[0] = ( R & 0xFF000000 ) >> 24;
|
||||
block[1] = ( R & 0x00FF0000 ) >> 16;
|
||||
block[2] = ( R & 0x0000FF00 ) >> 8;
|
||||
block[3] = ( R & 0x000000FF );
|
||||
block[4] = ( L & 0xFF000000 ) >> 24;
|
||||
block[5] = ( L & 0x00FF0000 ) >> 16;
|
||||
block[6] = ( L & 0x0000FF00 ) >> 8;
|
||||
block[7] = ( L & 0x000000FF );
|
||||
}
|
||||
|
||||
/* fetch a uint8 from an array of uint32s */
|
||||
#define b(a,n) (((a)[n/4] >> (24-((n&3)*8))) & 0xFF)
|
||||
|
||||
/* key schedule round functions */
|
||||
|
||||
#define XZRound(T, F, ki1, ki2, ki3, ki4, \
|
||||
si11, si12, si13, si14, si15,\
|
||||
si25,\
|
||||
si35,\
|
||||
si45 ) \
|
||||
T[0] = F[ki1] ^ S5[si11 ] ^ S6[si12 ] ^ S7[si13 ] ^ S8[si14 ] ^ S7[si15];\
|
||||
T[1] = F[ki2] ^ S5[b(T, 0)] ^ S6[b(T,2)] ^ S7[b(T, 1)] ^ S8[b(T,3)] ^ S8[si25];\
|
||||
T[2] = F[ki3] ^ S5[b(T, 7)] ^ S6[b(T,6)] ^ S7[b(T, 5)] ^ S8[b(T,4)] ^ S5[si35];\
|
||||
T[3] = F[ki4] ^ S5[b(T,10)] ^ S6[b(T,9)] ^ S7[b(T,11)] ^ S8[b(T,8)] ^ S6[si45];
|
||||
|
||||
#define zxround() XZRound(z, x, 0, 2, 3, 1, \
|
||||
b(x,13), b(x,15), b(x,12), b(x,14),\
|
||||
b(x, 8), b(x,10), b(x, 9), b(x,11))
|
||||
|
||||
#define xzround() XZRound(x, z, 2, 0, 1, 3, \
|
||||
b(z,5), b(z,7), b(z,4), b(z,6), \
|
||||
b(z,0), b(z,2), b(z,1), b(z,3))
|
||||
|
||||
#define Kround(T, base, F,\
|
||||
i11, i12, i13, i14, i15,\
|
||||
i21, i22, i23, i24, i25,\
|
||||
i31, i32, i33, i34, i35,\
|
||||
i41, i42, i43, i44, i45)\
|
||||
T[base+0] = S5[b(F,i11)] ^ S6[b(F,i12)] ^ S7[b(F,i13)] ^ S8[b(F,i14)] ^ S5[b(F,i15)];\
|
||||
T[base+1] = S5[b(F,i21)] ^ S6[b(F,i22)] ^ S7[b(F,i23)] ^ S8[b(F,i24)] ^ S6[b(F,i25)];\
|
||||
T[base+2] = S5[b(F,i31)] ^ S6[b(F,i32)] ^ S7[b(F,i33)] ^ S8[b(F,i34)] ^ S7[b(F,i35)];\
|
||||
T[base+3] = S5[b(F,i41)] ^ S6[b(F,i42)] ^ S7[b(F,i43)] ^ S8[b(F,i44)] ^ S8[b(F,i45)];
|
||||
|
||||
/* generates sixteen 32-bit subkeys based on a 4x32-bit input key;
|
||||
modifies the input key *in as well. */
|
||||
static void schedulekeys_half(uint32 *in, uint32 *keys)
|
||||
{
|
||||
uint32 x[4], z[4];
|
||||
|
||||
x[0] = in[0];
|
||||
x[1] = in[1];
|
||||
x[2] = in[2];
|
||||
x[3] = in[3];
|
||||
|
||||
zxround();
|
||||
Kround(keys, 0, z,
|
||||
8, 9, 7, 6, 2,
|
||||
10, 11, 5, 4, 6,
|
||||
12, 13, 3, 2, 9,
|
||||
14, 15, 1, 0, 12);
|
||||
xzround();
|
||||
Kround(keys, 4, x,
|
||||
3, 2, 12, 13, 8,
|
||||
1, 0, 14, 15, 13,
|
||||
7, 6, 8, 9, 3,
|
||||
5, 4, 10, 11, 7);
|
||||
zxround();
|
||||
Kround(keys, 8, z,
|
||||
3, 2, 12, 13, 9,
|
||||
1, 0, 14, 15, 12,
|
||||
7, 6, 8, 9, 2,
|
||||
5, 4, 10, 11, 6);
|
||||
xzround();
|
||||
Kround(keys, 12, x,
|
||||
8, 9, 7, 6, 3,
|
||||
10, 11, 5, 4, 7,
|
||||
12, 13, 3, 2, 8,
|
||||
14, 15, 1, 0, 13);
|
||||
|
||||
in[0] = x[0];
|
||||
in[1] = x[1];
|
||||
in[2] = x[2];
|
||||
in[3] = x[3];
|
||||
}
|
||||
|
||||
/* generates a key schedule from an input key */
|
||||
static void castschedulekeys(block_state *schedule, uint8 *key, int keybytes)
|
||||
{
|
||||
uint32 x[4];
|
||||
uint8 paddedkey[16];
|
||||
uint32 Kr_wide[16];
|
||||
int i;
|
||||
|
||||
for(i = 0; i < keybytes; i++)
|
||||
paddedkey[i] = key[i];
|
||||
for( ; i < 16 ; i++)
|
||||
paddedkey[i] = 0;
|
||||
|
||||
if (keybytes <= 10)
|
||||
schedule->rounds = 12;
|
||||
else
|
||||
schedule->rounds = 16;
|
||||
|
||||
x[0] = fetch(paddedkey, 0);
|
||||
x[1] = fetch(paddedkey, 4);
|
||||
x[2] = fetch(paddedkey, 8);
|
||||
x[3] = fetch(paddedkey, 12);
|
||||
|
||||
schedulekeys_half(x, schedule->Km);
|
||||
schedulekeys_half(x, Kr_wide);
|
||||
|
||||
for(i = 0; i < 16; i ++) {
|
||||
/* The Kr[] subkeys are used for 32-bit circular shifts,
|
||||
so we only need to keep them modulo 32 */
|
||||
schedule->Kr[i] = (uint8)(Kr_wide[i] & 0x1F);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
/* This performs a variety of encryptions and verifies that the results
|
||||
match those specified in RFC2144 appendix B. Also verifies that
|
||||
decryption restores the original data. */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static block_state sched;
|
||||
|
||||
void encrypt(key, keylen, in, out)
|
||||
uint8 *key;
|
||||
int keylen;
|
||||
uint8 *in, *out;
|
||||
{
|
||||
int i;
|
||||
uint8 k[16];
|
||||
|
||||
castschedulekeys(&sched, key, keylen);
|
||||
|
||||
for(i = 0; i < 8; i++)
|
||||
out[i] = in[i];
|
||||
castcrypt(&sched, out, 0);
|
||||
}
|
||||
|
||||
void tst(key, keylen, data, result)
|
||||
uint8 *key;
|
||||
int keylen;
|
||||
uint8 *data, *result;
|
||||
{
|
||||
uint8 d[8];
|
||||
int i;
|
||||
|
||||
encrypt(key, keylen, data, d);
|
||||
|
||||
for(i = 0; i < 8; i++)
|
||||
if (d[i] != result[i])
|
||||
break;
|
||||
|
||||
if (i == 8) {
|
||||
printf("-- test ok (encrypt)\n");
|
||||
} else {
|
||||
for(i = 0; i < 8; i++)
|
||||
printf(" %02x", d[i]);
|
||||
printf(" (computed)\n");
|
||||
for(i = 0; i < 8; i++)
|
||||
printf(" %02x", result[i]);
|
||||
printf(" (expected)\n");
|
||||
}
|
||||
|
||||
/* uses key schedule already set up */
|
||||
castcrypt(&sched, d, 1);
|
||||
if (bcmp(d, data, 8))
|
||||
printf(" test FAILED (decrypt)\n");
|
||||
else
|
||||
printf(" test ok (decrypt)\n");
|
||||
|
||||
}
|
||||
|
||||
uint8 key[16] = { 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78,
|
||||
0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A };
|
||||
uint8 data[8] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF };
|
||||
|
||||
/* expected results of encrypting the above with 128, 80, and 40
|
||||
bits of key length */
|
||||
uint8 out1[8] = { 0x23, 0x8B, 0x4F, 0xE5, 0x84, 0x7E, 0x44, 0xB2 };
|
||||
uint8 out2[8] = { 0xEB, 0x6A, 0x71, 0x1A, 0x2C, 0x02, 0x27, 0x1B };
|
||||
uint8 out3[8] = { 0x7A, 0xC8, 0x16, 0xD1, 0x6E, 0x9B, 0x30, 0x2E };
|
||||
|
||||
/* expected results of the "full maintenance test" */
|
||||
uint8 afinal[16] = { 0xEE, 0xA9, 0xD0, 0xA2, 0x49, 0xFD, 0x3B, 0xA6,
|
||||
0xB3, 0x43, 0x6F, 0xB8, 0x9D, 0x6D, 0xCA, 0x92 };
|
||||
uint8 bfinal[16] = { 0xB2, 0xC9, 0x5E, 0xB0, 0x0C, 0x31, 0xAD, 0x71,
|
||||
0x80, 0xAC, 0x05, 0xB8, 0xE8, 0x3D, 0x69, 0x6E };
|
||||
|
||||
main()
|
||||
{
|
||||
/* Appendix B.1 : Single Plaintext-Key-Ciphertext Sets */
|
||||
tst(key, 16, data, out1);
|
||||
tst(key, 10, data, out2);
|
||||
tst(key, 5, data, out3);
|
||||
|
||||
/* Appendix B.2 : Full Maintenance Test */
|
||||
{
|
||||
uint8 abuf[16];
|
||||
uint8 bbuf[16];
|
||||
int i;
|
||||
|
||||
bcopy(key, abuf, 16);
|
||||
bcopy(key, bbuf, 16);
|
||||
|
||||
printf("\nrunning full maintenance test...\n");
|
||||
|
||||
for(i = 0; i < 1000000; i++) {
|
||||
castschedulekeys(&sched, bbuf, 16);
|
||||
castcrypt(&sched, abuf, 0);
|
||||
castcrypt(&sched, abuf+8, 0);
|
||||
|
||||
castschedulekeys(&sched, abuf, 16);
|
||||
castcrypt(&sched, bbuf, 0);
|
||||
castcrypt(&sched, bbuf+8, 0);
|
||||
|
||||
if (!(i % 10000)) {
|
||||
fprintf(stdout, "\r%d%% ", i / 10000);
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
printf("\r \r");
|
||||
|
||||
for(i = 0; i < 16; i ++)
|
||||
if (abuf[i] != afinal[i] || bbuf[i] != bfinal[i])
|
||||
break;
|
||||
|
||||
if(i == 16) {
|
||||
printf("-- full maintenance test ok\n");
|
||||
} else {
|
||||
for(i = 0; i < 16; i++)
|
||||
printf(" %02x", abuf[i]);
|
||||
printf("\n");
|
||||
for(i = 0; i < 16; i++)
|
||||
printf(" %02x", bbuf[i]);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
printf("running maintenance test in reverse...\n");
|
||||
for(i = 0; i < 1000000; i++) {
|
||||
castschedulekeys(&sched, abuf, 16);
|
||||
castcrypt(&sched, bbuf+8, 1);
|
||||
castcrypt(&sched, bbuf, 1);
|
||||
|
||||
castschedulekeys(&sched, bbuf, 16);
|
||||
castcrypt(&sched, abuf+8, 1);
|
||||
castcrypt(&sched, abuf, 1);
|
||||
|
||||
if (!(i % 10000)) {
|
||||
fprintf(stdout, "\r%d%% ", i / 10000);
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
printf("\r \r");
|
||||
if (bcmp(abuf, key, 16) || bcmp(bbuf, key, 16))
|
||||
printf("-- reverse maintenance test FAILED\n");
|
||||
else
|
||||
printf("-- reverse maintenance test ok\n");
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void
|
||||
block_init(block_state *self, unsigned char *key, int keylength)
|
||||
{
|
||||
/* presumably this will optimize out */
|
||||
if (sizeof(uint32) < 4 || sizeof(uint8) != 1) {
|
||||
PyErr_SetString(PyExc_SystemError,
|
||||
"CAST module compiled with bad typedefs!");
|
||||
}
|
||||
|
||||
/* make sure the key length is within bounds */
|
||||
if (keylength < 5 || keylength > 16) {
|
||||
PyErr_SetString(PyExc_ValueError, "CAST key must be "
|
||||
"at least 5 bytes and no more than 16 bytes long");
|
||||
return;
|
||||
}
|
||||
|
||||
/* do the actual key schedule setup */
|
||||
castschedulekeys(self, key, keylength);
|
||||
}
|
||||
|
||||
static void
|
||||
block_encrypt(block_state *self, unsigned char *in,
|
||||
unsigned char *out)
|
||||
{
|
||||
memcpy(out, in, 8);
|
||||
castcrypt(self, out, 0);
|
||||
}
|
||||
|
||||
static void block_decrypt(block_state *self,
|
||||
unsigned char *in,
|
||||
unsigned char *out)
|
||||
{
|
||||
memcpy(out, in, 8);
|
||||
castcrypt(self, out, 1);
|
||||
}
|
||||
|
||||
#include "block_template.c"
|
@ -1,665 +0,0 @@
|
||||
/*
|
||||
* des.c : Source code for the DES block cipher
|
||||
*
|
||||
* Part of the Python Cryptography Toolkit
|
||||
*
|
||||
* Distribute and use freely; there are no restrictions on further
|
||||
* dissemination and usage except those imposed by the laws of your
|
||||
* country of residence.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Python.h"
|
||||
|
||||
/* des.c */
|
||||
/* Copyright (C) 1993 Eric Young */
|
||||
/* Integrated into the PCT by A.M. Kuchling, November 1994 */
|
||||
|
||||
#define MODULE_NAME DES
|
||||
#define BLOCK_SIZE 8
|
||||
#define KEY_SIZE 8
|
||||
|
||||
|
||||
typedef unsigned char des_cblock[8];
|
||||
|
||||
/* ecb_enc.c */
|
||||
/* Copyright (C) 1993 Eric Young - see README for more details */
|
||||
|
||||
#define c2l(c,l) (l =((unsigned long)(*((c)++))) , \
|
||||
l|=((unsigned long)(*((c)++)))<< 8, \
|
||||
l|=((unsigned long)(*((c)++)))<<16, \
|
||||
l|=((unsigned long)(*((c)++)))<<24)
|
||||
|
||||
/* NOTE - c is not incremented as per c2l */
|
||||
#define c2ln(c,l1,l2,n) { \
|
||||
c+=n; \
|
||||
l1=l2=0; \
|
||||
switch (n) { \
|
||||
case 8: l2|=((unsigned long)(*(--(c))))<<24; \
|
||||
case 7: l2|=((unsigned long)(*(--(c))))<<16; \
|
||||
case 6: l2|=((unsigned long)(*(--(c))))<< 8; \
|
||||
case 5: l2|=((unsigned long)(*(--(c)))); \
|
||||
case 4: l1|=((unsigned long)(*(--(c))))<<24; \
|
||||
case 3: l1|=((unsigned long)(*(--(c))))<<16; \
|
||||
case 2: l1|=((unsigned long)(*(--(c))))<< 8; \
|
||||
case 1: l1|=((unsigned long)(*(--(c)))); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
|
||||
*((c)++)=(unsigned char)(((l)>> 8)&0xff), \
|
||||
*((c)++)=(unsigned char)(((l)>>16)&0xff), \
|
||||
*((c)++)=(unsigned char)(((l)>>24)&0xff))
|
||||
|
||||
/* replacements for htonl and ntohl since I have no idea what to do
|
||||
* when faced with machines with 8 byte longs. */
|
||||
#define HDRSIZE 4
|
||||
|
||||
#define n2l(c,l) (l =((unsigned long)(*((c)++)))<<24, \
|
||||
l|=((unsigned long)(*((c)++)))<<16, \
|
||||
l|=((unsigned long)(*((c)++)))<< 8, \
|
||||
l|=((unsigned long)(*((c)++))))
|
||||
|
||||
#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \
|
||||
*((c)++)=(unsigned char)(((l)>>16)&0xff), \
|
||||
*((c)++)=(unsigned char)(((l)>> 8)&0xff), \
|
||||
*((c)++)=(unsigned char)(((l) )&0xff))
|
||||
|
||||
/* NOTE - c is not incremented as per l2c */
|
||||
#define l2cn(l1,l2,c,n) { \
|
||||
c+=n; \
|
||||
switch (n) { \
|
||||
case 8: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \
|
||||
case 7: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \
|
||||
case 6: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \
|
||||
case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \
|
||||
case 4: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \
|
||||
case 3: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \
|
||||
case 2: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \
|
||||
case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define D_ENCRYPT(L,R,S) \
|
||||
u=(R^s[S ]); \
|
||||
t=R^s[S+1]; \
|
||||
t=((t>>4)+(t<<28)); \
|
||||
L^= des_SPtrans[1][(t )&0x3f]| \
|
||||
des_SPtrans[3][(t>> 8)&0x3f]| \
|
||||
des_SPtrans[5][(t>>16)&0x3f]| \
|
||||
des_SPtrans[7][(t>>24)&0x3f]| \
|
||||
des_SPtrans[0][(u )&0x3f]| \
|
||||
des_SPtrans[2][(u>> 8)&0x3f]| \
|
||||
des_SPtrans[4][(u>>16)&0x3f]| \
|
||||
des_SPtrans[6][(u>>24)&0x3f];
|
||||
|
||||
/* IP and FP
|
||||
* The problem is more of a geometric problem that random bit fiddling.
|
||||
0 1 2 3 4 5 6 7 62 54 46 38 30 22 14 6
|
||||
8 9 10 11 12 13 14 15 60 52 44 36 28 20 12 4
|
||||
16 17 18 19 20 21 22 23 58 50 42 34 26 18 10 2
|
||||
24 25 26 27 28 29 30 31 to 56 48 40 32 24 16 8 0
|
||||
|
||||
32 33 34 35 36 37 38 39 63 55 47 39 31 23 15 7
|
||||
40 41 42 43 44 45 46 47 61 53 45 37 29 21 13 5
|
||||
48 49 50 51 52 53 54 55 59 51 43 35 27 19 11 3
|
||||
56 57 58 59 60 61 62 63 57 49 41 33 25 17 9 1
|
||||
|
||||
The output has been subject to swaps of the form
|
||||
0 1 -> 3 1 but the odd and even bits have been put into
|
||||
2 3 2 0
|
||||
different words. The main trick is to remember that
|
||||
t=((l>>size)^r)&(mask);
|
||||
r^=t;
|
||||
l^=(t<<size);
|
||||
can be used to swap and move bits between words.
|
||||
|
||||
So l = 0 1 2 3 r = 16 17 18 19
|
||||
4 5 6 7 20 21 22 23
|
||||
8 9 10 11 24 25 26 27
|
||||
12 13 14 15 28 29 30 31
|
||||
becomes (for size == 2 and mask == 0x3333)
|
||||
t = 2^16 3^17 -- -- l = 0 1 16 17 r = 2 3 18 19
|
||||
6^20 7^21 -- -- 4 5 20 21 6 7 22 23
|
||||
10^24 11^25 -- -- 8 9 24 25 10 11 24 25
|
||||
14^28 15^29 -- -- 12 13 28 29 14 15 28 29
|
||||
|
||||
Thanks for hints from Richard Outerbridge - he told me IP&FP
|
||||
could be done in 15 xor, 10 shifts and 5 ands.
|
||||
When I finally started to think of the problem in 2D
|
||||
I first got ~42 operations without xors. When I remembered
|
||||
how to use xors :-) I got it to its final state.
|
||||
*/
|
||||
#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
|
||||
(b)^=(t),\
|
||||
(a)^=((t)<<(n)))
|
||||
|
||||
|
||||
|
||||
/* spr.h */
|
||||
/* Copyright (C) 1993 Eric Young - see README for more details */
|
||||
static unsigned long des_SPtrans[8][64]={
|
||||
/* nibble 0 */
|
||||
{0x00820200, 0x00020000, 0x80800000, 0x80820200,
|
||||
0x00800000, 0x80020200, 0x80020000, 0x80800000,
|
||||
0x80020200, 0x00820200, 0x00820000, 0x80000200,
|
||||
0x80800200, 0x00800000, 0x00000000, 0x80020000,
|
||||
0x00020000, 0x80000000, 0x00800200, 0x00020200,
|
||||
0x80820200, 0x00820000, 0x80000200, 0x00800200,
|
||||
0x80000000, 0x00000200, 0x00020200, 0x80820000,
|
||||
0x00000200, 0x80800200, 0x80820000, 0x00000000,
|
||||
0x00000000, 0x80820200, 0x00800200, 0x80020000,
|
||||
0x00820200, 0x00020000, 0x80000200, 0x00800200,
|
||||
0x80820000, 0x00000200, 0x00020200, 0x80800000,
|
||||
0x80020200, 0x80000000, 0x80800000, 0x00820000,
|
||||
0x80820200, 0x00020200, 0x00820000, 0x80800200,
|
||||
0x00800000, 0x80000200, 0x80020000, 0x00000000,
|
||||
0x00020000, 0x00800000, 0x80800200, 0x00820200,
|
||||
0x80000000, 0x80820000, 0x00000200, 0x80020200},
|
||||
|
||||
/* nibble 1 */
|
||||
{0x10042004, 0x00000000, 0x00042000, 0x10040000,
|
||||
0x10000004, 0x00002004, 0x10002000, 0x00042000,
|
||||
0x00002000, 0x10040004, 0x00000004, 0x10002000,
|
||||
0x00040004, 0x10042000, 0x10040000, 0x00000004,
|
||||
0x00040000, 0x10002004, 0x10040004, 0x00002000,
|
||||
0x00042004, 0x10000000, 0x00000000, 0x00040004,
|
||||
0x10002004, 0x00042004, 0x10042000, 0x10000004,
|
||||
0x10000000, 0x00040000, 0x00002004, 0x10042004,
|
||||
0x00040004, 0x10042000, 0x10002000, 0x00042004,
|
||||
0x10042004, 0x00040004, 0x10000004, 0x00000000,
|
||||
0x10000000, 0x00002004, 0x00040000, 0x10040004,
|
||||
0x00002000, 0x10000000, 0x00042004, 0x10002004,
|
||||
0x10042000, 0x00002000, 0x00000000, 0x10000004,
|
||||
0x00000004, 0x10042004, 0x00042000, 0x10040000,
|
||||
0x10040004, 0x00040000, 0x00002004, 0x10002000,
|
||||
0x10002004, 0x00000004, 0x10040000, 0x00042000},
|
||||
|
||||
/* nibble 2 */
|
||||
{0x41000000, 0x01010040, 0x00000040, 0x41000040,
|
||||
0x40010000, 0x01000000, 0x41000040, 0x00010040,
|
||||
0x01000040, 0x00010000, 0x01010000, 0x40000000,
|
||||
0x41010040, 0x40000040, 0x40000000, 0x41010000,
|
||||
0x00000000, 0x40010000, 0x01010040, 0x00000040,
|
||||
0x40000040, 0x41010040, 0x00010000, 0x41000000,
|
||||
0x41010000, 0x01000040, 0x40010040, 0x01010000,
|
||||
0x00010040, 0x00000000, 0x01000000, 0x40010040,
|
||||
0x01010040, 0x00000040, 0x40000000, 0x00010000,
|
||||
0x40000040, 0x40010000, 0x01010000, 0x41000040,
|
||||
0x00000000, 0x01010040, 0x00010040, 0x41010000,
|
||||
0x40010000, 0x01000000, 0x41010040, 0x40000000,
|
||||
0x40010040, 0x41000000, 0x01000000, 0x41010040,
|
||||
0x00010000, 0x01000040, 0x41000040, 0x00010040,
|
||||
0x01000040, 0x00000000, 0x41010000, 0x40000040,
|
||||
0x41000000, 0x40010040, 0x00000040, 0x01010000},
|
||||
|
||||
/* nibble 3 */
|
||||
{0x00100402, 0x04000400, 0x00000002, 0x04100402,
|
||||
0x00000000, 0x04100000, 0x04000402, 0x00100002,
|
||||
0x04100400, 0x04000002, 0x04000000, 0x00000402,
|
||||
0x04000002, 0x00100402, 0x00100000, 0x04000000,
|
||||
0x04100002, 0x00100400, 0x00000400, 0x00000002,
|
||||
0x00100400, 0x04000402, 0x04100000, 0x00000400,
|
||||
0x00000402, 0x00000000, 0x00100002, 0x04100400,
|
||||
0x04000400, 0x04100002, 0x04100402, 0x00100000,
|
||||
0x04100002, 0x00000402, 0x00100000, 0x04000002,
|
||||
0x00100400, 0x04000400, 0x00000002, 0x04100000,
|
||||
0x04000402, 0x00000000, 0x00000400, 0x00100002,
|
||||
0x00000000, 0x04100002, 0x04100400, 0x00000400,
|
||||
0x04000000, 0x04100402, 0x00100402, 0x00100000,
|
||||
0x04100402, 0x00000002, 0x04000400, 0x00100402,
|
||||
0x00100002, 0x00100400, 0x04100000, 0x04000402,
|
||||
0x00000402, 0x04000000, 0x04000002, 0x04100400},
|
||||
|
||||
/* nibble 4 */
|
||||
{0x02000000, 0x00004000, 0x00000100, 0x02004108,
|
||||
0x02004008, 0x02000100, 0x00004108, 0x02004000,
|
||||
0x00004000, 0x00000008, 0x02000008, 0x00004100,
|
||||
0x02000108, 0x02004008, 0x02004100, 0x00000000,
|
||||
0x00004100, 0x02000000, 0x00004008, 0x00000108,
|
||||
0x02000100, 0x00004108, 0x00000000, 0x02000008,
|
||||
0x00000008, 0x02000108, 0x02004108, 0x00004008,
|
||||
0x02004000, 0x00000100, 0x00000108, 0x02004100,
|
||||
0x02004100, 0x02000108, 0x00004008, 0x02004000,
|
||||
0x00004000, 0x00000008, 0x02000008, 0x02000100,
|
||||
0x02000000, 0x00004100, 0x02004108, 0x00000000,
|
||||
0x00004108, 0x02000000, 0x00000100, 0x00004008,
|
||||
0x02000108, 0x00000100, 0x00000000, 0x02004108,
|
||||
0x02004008, 0x02004100, 0x00000108, 0x00004000,
|
||||
0x00004100, 0x02004008, 0x02000100, 0x00000108,
|
||||
0x00000008, 0x00004108, 0x02004000, 0x02000008},
|
||||
|
||||
/* nibble 5 */
|
||||
{0x20000010, 0x00080010, 0x00000000, 0x20080800,
|
||||
0x00080010, 0x00000800, 0x20000810, 0x00080000,
|
||||
0x00000810, 0x20080810, 0x00080800, 0x20000000,
|
||||
0x20000800, 0x20000010, 0x20080000, 0x00080810,
|
||||
0x00080000, 0x20000810, 0x20080010, 0x00000000,
|
||||
0x00000800, 0x00000010, 0x20080800, 0x20080010,
|
||||
0x20080810, 0x20080000, 0x20000000, 0x00000810,
|
||||
0x00000010, 0x00080800, 0x00080810, 0x20000800,
|
||||
0x00000810, 0x20000000, 0x20000800, 0x00080810,
|
||||
0x20080800, 0x00080010, 0x00000000, 0x20000800,
|
||||
0x20000000, 0x00000800, 0x20080010, 0x00080000,
|
||||
0x00080010, 0x20080810, 0x00080800, 0x00000010,
|
||||
0x20080810, 0x00080800, 0x00080000, 0x20000810,
|
||||
0x20000010, 0x20080000, 0x00080810, 0x00000000,
|
||||
0x00000800, 0x20000010, 0x20000810, 0x20080800,
|
||||
0x20080000, 0x00000810, 0x00000010, 0x20080010},
|
||||
|
||||
/* nibble 6 */
|
||||
{0x00001000, 0x00000080, 0x00400080, 0x00400001,
|
||||
0x00401081, 0x00001001, 0x00001080, 0x00000000,
|
||||
0x00400000, 0x00400081, 0x00000081, 0x00401000,
|
||||
0x00000001, 0x00401080, 0x00401000, 0x00000081,
|
||||
0x00400081, 0x00001000, 0x00001001, 0x00401081,
|
||||
0x00000000, 0x00400080, 0x00400001, 0x00001080,
|
||||
0x00401001, 0x00001081, 0x00401080, 0x00000001,
|
||||
0x00001081, 0x00401001, 0x00000080, 0x00400000,
|
||||
0x00001081, 0x00401000, 0x00401001, 0x00000081,
|
||||
0x00001000, 0x00000080, 0x00400000, 0x00401001,
|
||||
0x00400081, 0x00001081, 0x00001080, 0x00000000,
|
||||
0x00000080, 0x00400001, 0x00000001, 0x00400080,
|
||||
0x00000000, 0x00400081, 0x00400080, 0x00001080,
|
||||
0x00000081, 0x00001000, 0x00401081, 0x00400000,
|
||||
0x00401080, 0x00000001, 0x00001001, 0x00401081,
|
||||
0x00400001, 0x00401080, 0x00401000, 0x00001001},
|
||||
|
||||
/* nibble 7 */
|
||||
{0x08200020, 0x08208000, 0x00008020, 0x00000000,
|
||||
0x08008000, 0x00200020, 0x08200000, 0x08208020,
|
||||
0x00000020, 0x08000000, 0x00208000, 0x00008020,
|
||||
0x00208020, 0x08008020, 0x08000020, 0x08200000,
|
||||
0x00008000, 0x00208020, 0x00200020, 0x08008000,
|
||||
0x08208020, 0x08000020, 0x00000000, 0x00208000,
|
||||
0x08000000, 0x00200000, 0x08008020, 0x08200020,
|
||||
0x00200000, 0x00008000, 0x08208000, 0x00000020,
|
||||
0x00200000, 0x00008000, 0x08000020, 0x08208020,
|
||||
0x00008020, 0x08000000, 0x00000000, 0x00208000,
|
||||
0x08200020, 0x08008020, 0x08008000, 0x00200020,
|
||||
0x08208000, 0x00000020, 0x00200020, 0x08008000,
|
||||
0x08208020, 0x00200000, 0x08200000, 0x08000020,
|
||||
0x00208000, 0x00008020, 0x08008020, 0x08200000,
|
||||
0x00000020, 0x08208000, 0x00208020, 0x00000000,
|
||||
0x08000000, 0x08200020, 0x00008000, 0x00208020}};
|
||||
|
||||
static unsigned long des_skb[8][64]={
|
||||
/* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
|
||||
{0x00000000,0x00000010,0x20000000,0x20000010,
|
||||
0x00010000,0x00010010,0x20010000,0x20010010,
|
||||
0x00000800,0x00000810,0x20000800,0x20000810,
|
||||
0x00010800,0x00010810,0x20010800,0x20010810,
|
||||
0x00000020,0x00000030,0x20000020,0x20000030,
|
||||
0x00010020,0x00010030,0x20010020,0x20010030,
|
||||
0x00000820,0x00000830,0x20000820,0x20000830,
|
||||
0x00010820,0x00010830,0x20010820,0x20010830,
|
||||
0x00080000,0x00080010,0x20080000,0x20080010,
|
||||
0x00090000,0x00090010,0x20090000,0x20090010,
|
||||
0x00080800,0x00080810,0x20080800,0x20080810,
|
||||
0x00090800,0x00090810,0x20090800,0x20090810,
|
||||
0x00080020,0x00080030,0x20080020,0x20080030,
|
||||
0x00090020,0x00090030,0x20090020,0x20090030,
|
||||
0x00080820,0x00080830,0x20080820,0x20080830,
|
||||
0x00090820,0x00090830,0x20090820,0x20090830},
|
||||
/* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
|
||||
{0x00000000,0x02000000,0x00002000,0x02002000,
|
||||
0x00200000,0x02200000,0x00202000,0x02202000,
|
||||
0x00000004,0x02000004,0x00002004,0x02002004,
|
||||
0x00200004,0x02200004,0x00202004,0x02202004,
|
||||
0x00000400,0x02000400,0x00002400,0x02002400,
|
||||
0x00200400,0x02200400,0x00202400,0x02202400,
|
||||
0x00000404,0x02000404,0x00002404,0x02002404,
|
||||
0x00200404,0x02200404,0x00202404,0x02202404,
|
||||
0x10000000,0x12000000,0x10002000,0x12002000,
|
||||
0x10200000,0x12200000,0x10202000,0x12202000,
|
||||
0x10000004,0x12000004,0x10002004,0x12002004,
|
||||
0x10200004,0x12200004,0x10202004,0x12202004,
|
||||
0x10000400,0x12000400,0x10002400,0x12002400,
|
||||
0x10200400,0x12200400,0x10202400,0x12202400,
|
||||
0x10000404,0x12000404,0x10002404,0x12002404,
|
||||
0x10200404,0x12200404,0x10202404,0x12202404},
|
||||
/* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
|
||||
{0x00000000,0x00000001,0x00040000,0x00040001,
|
||||
0x01000000,0x01000001,0x01040000,0x01040001,
|
||||
0x00000002,0x00000003,0x00040002,0x00040003,
|
||||
0x01000002,0x01000003,0x01040002,0x01040003,
|
||||
0x00000200,0x00000201,0x00040200,0x00040201,
|
||||
0x01000200,0x01000201,0x01040200,0x01040201,
|
||||
0x00000202,0x00000203,0x00040202,0x00040203,
|
||||
0x01000202,0x01000203,0x01040202,0x01040203,
|
||||
0x08000000,0x08000001,0x08040000,0x08040001,
|
||||
0x09000000,0x09000001,0x09040000,0x09040001,
|
||||
0x08000002,0x08000003,0x08040002,0x08040003,
|
||||
0x09000002,0x09000003,0x09040002,0x09040003,
|
||||
0x08000200,0x08000201,0x08040200,0x08040201,
|
||||
0x09000200,0x09000201,0x09040200,0x09040201,
|
||||
0x08000202,0x08000203,0x08040202,0x08040203,
|
||||
0x09000202,0x09000203,0x09040202,0x09040203},
|
||||
/* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
|
||||
{0x00000000,0x00100000,0x00000100,0x00100100,
|
||||
0x00000008,0x00100008,0x00000108,0x00100108,
|
||||
0x00001000,0x00101000,0x00001100,0x00101100,
|
||||
0x00001008,0x00101008,0x00001108,0x00101108,
|
||||
0x04000000,0x04100000,0x04000100,0x04100100,
|
||||
0x04000008,0x04100008,0x04000108,0x04100108,
|
||||
0x04001000,0x04101000,0x04001100,0x04101100,
|
||||
0x04001008,0x04101008,0x04001108,0x04101108,
|
||||
0x00020000,0x00120000,0x00020100,0x00120100,
|
||||
0x00020008,0x00120008,0x00020108,0x00120108,
|
||||
0x00021000,0x00121000,0x00021100,0x00121100,
|
||||
0x00021008,0x00121008,0x00021108,0x00121108,
|
||||
0x04020000,0x04120000,0x04020100,0x04120100,
|
||||
0x04020008,0x04120008,0x04020108,0x04120108,
|
||||
0x04021000,0x04121000,0x04021100,0x04121100,
|
||||
0x04021008,0x04121008,0x04021108,0x04121108},
|
||||
/* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
|
||||
{0x00000000,0x10000000,0x00010000,0x10010000,
|
||||
0x00000004,0x10000004,0x00010004,0x10010004,
|
||||
0x20000000,0x30000000,0x20010000,0x30010000,
|
||||
0x20000004,0x30000004,0x20010004,0x30010004,
|
||||
0x00100000,0x10100000,0x00110000,0x10110000,
|
||||
0x00100004,0x10100004,0x00110004,0x10110004,
|
||||
0x20100000,0x30100000,0x20110000,0x30110000,
|
||||
0x20100004,0x30100004,0x20110004,0x30110004,
|
||||
0x00001000,0x10001000,0x00011000,0x10011000,
|
||||
0x00001004,0x10001004,0x00011004,0x10011004,
|
||||
0x20001000,0x30001000,0x20011000,0x30011000,
|
||||
0x20001004,0x30001004,0x20011004,0x30011004,
|
||||
0x00101000,0x10101000,0x00111000,0x10111000,
|
||||
0x00101004,0x10101004,0x00111004,0x10111004,
|
||||
0x20101000,0x30101000,0x20111000,0x30111000,
|
||||
0x20101004,0x30101004,0x20111004,0x30111004},
|
||||
/* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
|
||||
{0x00000000,0x08000000,0x00000008,0x08000008,
|
||||
0x00000400,0x08000400,0x00000408,0x08000408,
|
||||
0x00020000,0x08020000,0x00020008,0x08020008,
|
||||
0x00020400,0x08020400,0x00020408,0x08020408,
|
||||
0x00000001,0x08000001,0x00000009,0x08000009,
|
||||
0x00000401,0x08000401,0x00000409,0x08000409,
|
||||
0x00020001,0x08020001,0x00020009,0x08020009,
|
||||
0x00020401,0x08020401,0x00020409,0x08020409,
|
||||
0x02000000,0x0A000000,0x02000008,0x0A000008,
|
||||
0x02000400,0x0A000400,0x02000408,0x0A000408,
|
||||
0x02020000,0x0A020000,0x02020008,0x0A020008,
|
||||
0x02020400,0x0A020400,0x02020408,0x0A020408,
|
||||
0x02000001,0x0A000001,0x02000009,0x0A000009,
|
||||
0x02000401,0x0A000401,0x02000409,0x0A000409,
|
||||
0x02020001,0x0A020001,0x02020009,0x0A020009,
|
||||
0x02020401,0x0A020401,0x02020409,0x0A020409},
|
||||
/* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
|
||||
{0x00000000,0x00000100,0x00080000,0x00080100,
|
||||
0x01000000,0x01000100,0x01080000,0x01080100,
|
||||
0x00000010,0x00000110,0x00080010,0x00080110,
|
||||
0x01000010,0x01000110,0x01080010,0x01080110,
|
||||
0x00200000,0x00200100,0x00280000,0x00280100,
|
||||
0x01200000,0x01200100,0x01280000,0x01280100,
|
||||
0x00200010,0x00200110,0x00280010,0x00280110,
|
||||
0x01200010,0x01200110,0x01280010,0x01280110,
|
||||
0x00000200,0x00000300,0x00080200,0x00080300,
|
||||
0x01000200,0x01000300,0x01080200,0x01080300,
|
||||
0x00000210,0x00000310,0x00080210,0x00080310,
|
||||
0x01000210,0x01000310,0x01080210,0x01080310,
|
||||
0x00200200,0x00200300,0x00280200,0x00280300,
|
||||
0x01200200,0x01200300,0x01280200,0x01280300,
|
||||
0x00200210,0x00200310,0x00280210,0x00280310,
|
||||
0x01200210,0x01200310,0x01280210,0x01280310},
|
||||
/* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
|
||||
{0x00000000,0x04000000,0x00040000,0x04040000,
|
||||
0x00000002,0x04000002,0x00040002,0x04040002,
|
||||
0x00002000,0x04002000,0x00042000,0x04042000,
|
||||
0x00002002,0x04002002,0x00042002,0x04042002,
|
||||
0x00000020,0x04000020,0x00040020,0x04040020,
|
||||
0x00000022,0x04000022,0x00040022,0x04040022,
|
||||
0x00002020,0x04002020,0x00042020,0x04042020,
|
||||
0x00002022,0x04002022,0x00042022,0x04042022,
|
||||
0x00000800,0x04000800,0x00040800,0x04040800,
|
||||
0x00000802,0x04000802,0x00040802,0x04040802,
|
||||
0x00002800,0x04002800,0x00042800,0x04042800,
|
||||
0x00002802,0x04002802,0x00042802,0x04042802,
|
||||
0x00000820,0x04000820,0x00040820,0x04040820,
|
||||
0x00000822,0x04000822,0x00040822,0x04040822,
|
||||
0x00002820,0x04002820,0x00042820,0x04042820,
|
||||
0x00002822,0x04002822,0x00042822,0x04042822}
|
||||
};
|
||||
|
||||
typedef struct des_ks_struct
|
||||
{
|
||||
union {
|
||||
des_cblock _;
|
||||
/* make sure things are correct size on machines with
|
||||
* 8 byte longs */
|
||||
unsigned long pad[2];
|
||||
} ks;
|
||||
#define _ ks._
|
||||
} block_state[16];
|
||||
|
||||
static int des_encrypt(unsigned long *input, unsigned long *output,
|
||||
block_state ks, int encrypt)
|
||||
{
|
||||
unsigned long l,r,t,u;
|
||||
int i;
|
||||
unsigned long *s;
|
||||
|
||||
l=input[0];
|
||||
r=input[1];
|
||||
|
||||
/* do IP */
|
||||
PERM_OP(r,l,t, 4,0x0f0f0f0f);
|
||||
PERM_OP(l,r,t,16,0x0000ffff);
|
||||
PERM_OP(r,l,t, 2,0x33333333);
|
||||
PERM_OP(l,r,t, 8,0x00ff00ff);
|
||||
PERM_OP(r,l,t, 1,0x55555555);
|
||||
/* r and l are reversed - remember that :-) - fix
|
||||
* it in the next step */
|
||||
|
||||
/* Things have been modified so that the initial rotate is
|
||||
* done outside the loop. This required the
|
||||
* des_SPtrans values in sp.h to be rotated 1 bit to the right.
|
||||
* One perl script later and things have a 5% speed up on a sparc2.
|
||||
* Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
|
||||
* for pointing this out. */
|
||||
t=(r<<1)|(r>>31);
|
||||
r=(l<<1)|(l>>31);
|
||||
l=t;
|
||||
|
||||
/* clear the top bits on machines with 8byte longs */
|
||||
l&=0xffffffff;
|
||||
r&=0xffffffff;
|
||||
|
||||
s=(unsigned long *)ks;
|
||||
/* I don't know if it is worth the effort of loop unrolling the
|
||||
* inner loop */
|
||||
if (encrypt)
|
||||
{
|
||||
for (i=0; i<32; i+=4)
|
||||
{
|
||||
D_ENCRYPT(l,r,i+0); /* 1 */
|
||||
D_ENCRYPT(r,l,i+2); /* 2 */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=30; i>0; i-=4)
|
||||
{
|
||||
D_ENCRYPT(l,r,i-0); /* 16 */
|
||||
D_ENCRYPT(r,l,i-2); /* 15 */
|
||||
}
|
||||
}
|
||||
l=(l>>1)|(l<<31);
|
||||
r=(r>>1)|(r<<31);
|
||||
/* clear the top bits on machines with 8byte longs */
|
||||
l&=0xffffffff;
|
||||
r&=0xffffffff;
|
||||
|
||||
/* swap l and r
|
||||
* we will not do the swap so just remember they are
|
||||
* reversed for the rest of the subroutine
|
||||
* luckily FP fixes this problem :-) */
|
||||
|
||||
PERM_OP(r,l,t, 1,0x55555555);
|
||||
PERM_OP(l,r,t, 8,0x00ff00ff);
|
||||
PERM_OP(r,l,t, 2,0x33333333);
|
||||
PERM_OP(l,r,t,16,0x0000ffff);
|
||||
PERM_OP(r,l,t, 4,0x0f0f0f0f);
|
||||
|
||||
output[0]=l;
|
||||
output[1]=r;
|
||||
l=r=t=u=0;
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int des_ecb_encrypt(des_cblock *input, des_cblock *output,
|
||||
block_state ks, int encrypt)
|
||||
{
|
||||
register unsigned long l0,l1;
|
||||
register unsigned char *in,*out;
|
||||
unsigned long ll[2];
|
||||
|
||||
in=(unsigned char *)input;
|
||||
out=(unsigned char *)output;
|
||||
c2l(in,l0);
|
||||
c2l(in,l1);
|
||||
ll[0]=l0;
|
||||
ll[1]=l1;
|
||||
des_encrypt(ll,ll,ks,encrypt);
|
||||
l0=ll[0];
|
||||
l1=ll[1];
|
||||
l2c(l0,out);
|
||||
l2c(l1,out);
|
||||
l0=l1=ll[0]=ll[1]=0;
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void block_decrypt(block_state *state,
|
||||
unsigned char *in,
|
||||
unsigned char *out)
|
||||
{
|
||||
des_ecb_encrypt((des_cblock *)in, (des_cblock *)out, *state, 0);
|
||||
}
|
||||
|
||||
static void block_encrypt(block_state *state,
|
||||
unsigned char *in,
|
||||
unsigned char *out)
|
||||
{
|
||||
des_ecb_encrypt((des_cblock *)in, (des_cblock *)out, *state, 1);
|
||||
}
|
||||
|
||||
/* NOW DEFINED IN des_local.h
|
||||
* See ecb_encrypt.c for a pseudo description of these macros.
|
||||
* #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
|
||||
* (b)^=(t),\
|
||||
* (a)=((a)^((t)<<(n))))
|
||||
*/
|
||||
|
||||
#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
|
||||
(a)=(a)^(t)^(t>>(16-(n))))
|
||||
|
||||
static char shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0};
|
||||
|
||||
/* return 0 if key parity is odd (correct),
|
||||
* return -1 if key parity error,
|
||||
* return -2 if illegal weak key.
|
||||
*/
|
||||
static int des_set_key(des_cblock *key, block_state schedule)
|
||||
{
|
||||
register unsigned long c,d,t,s;
|
||||
register unsigned char *in;
|
||||
register unsigned long *k;
|
||||
register int i;
|
||||
|
||||
k=(unsigned long *)schedule;
|
||||
in=(unsigned char *)key;
|
||||
|
||||
c2l(in,c);
|
||||
c2l(in,d);
|
||||
|
||||
/* do PC1 in 60 simple operations */
|
||||
/* PERM_OP(d,c,t,4,0x0f0f0f0f);
|
||||
HPERM_OP(c,t,-2, 0xcccc0000);
|
||||
HPERM_OP(c,t,-1, 0xaaaa0000);
|
||||
HPERM_OP(c,t, 8, 0x00ff0000);
|
||||
HPERM_OP(c,t,-1, 0xaaaa0000);
|
||||
HPERM_OP(d,t,-8, 0xff000000);
|
||||
HPERM_OP(d,t, 8, 0x00ff0000);
|
||||
HPERM_OP(d,t, 2, 0x33330000);
|
||||
d=((d&0x00aa00aa)<<7)|((d&0x55005500)>>7)|(d&0xaa55aa55);
|
||||
d=(d>>8)|((c&0xf0000000)>>4);
|
||||
c&=0x0fffffff; */
|
||||
|
||||
/* I now do it in 47 simple operations :-)
|
||||
* Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
|
||||
* for the inspiration. :-) */
|
||||
PERM_OP (d,c,t,4,0x0f0f0f0f);
|
||||
HPERM_OP(c,t,-2,0xcccc0000);
|
||||
HPERM_OP(d,t,-2,0xcccc0000);
|
||||
PERM_OP (d,c,t,1,0x55555555);
|
||||
PERM_OP (c,d,t,8,0x00ff00ff);
|
||||
PERM_OP (d,c,t,1,0x55555555);
|
||||
d= (((d&0x000000ff)<<16)| (d&0x0000ff00) |
|
||||
((d&0x00ff0000)>>16)|((c&0xf0000000)>>4));
|
||||
c&=0x0fffffff;
|
||||
|
||||
for (i=0; i<16; i++)
|
||||
{
|
||||
if (shifts2[i])
|
||||
{ c=((c>>2)|(c<<26)); d=((d>>2)|(d<<26)); }
|
||||
else
|
||||
{ c=((c>>1)|(c<<27)); d=((d>>1)|(d<<27)); }
|
||||
c&=0x0fffffff;
|
||||
d&=0x0fffffff;
|
||||
/* could be a few less shifts but I am to lazy at this
|
||||
* point in time to investigate */
|
||||
s= des_skb[0][ (c )&0x3f ]|
|
||||
des_skb[1][((c>> 6)&0x03)|((c>> 7)&0x3c)]|
|
||||
des_skb[2][((c>>13)&0x0f)|((c>>14)&0x30)]|
|
||||
des_skb[3][((c>>20)&0x01)|((c>>21)&0x06) |
|
||||
((c>>22)&0x38)];
|
||||
t= des_skb[4][ (d )&0x3f ]|
|
||||
des_skb[5][((d>> 7)&0x03)|((d>> 8)&0x3c)]|
|
||||
des_skb[6][ (d>>15)&0x3f ]|
|
||||
des_skb[7][((d>>21)&0x0f)|((d>>22)&0x30)];
|
||||
|
||||
/* table contained 0213 4657 */
|
||||
*(k++)=((t<<16)|(s&0x0000ffff))&0xffffffff;
|
||||
s= ((s>>16)|(t&0xffff0000));
|
||||
|
||||
s=(s<<4)|(s>>28);
|
||||
*(k++)=s&0xffffffff;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
static const unsigned char odd_parity[256]={
|
||||
1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14,
|
||||
16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
|
||||
32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
|
||||
49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
|
||||
64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
|
||||
81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
|
||||
97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110,
|
||||
112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127,
|
||||
128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143,
|
||||
145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158,
|
||||
161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174,
|
||||
176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191,
|
||||
193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206,
|
||||
208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223,
|
||||
224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239,
|
||||
241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254};
|
||||
|
||||
static void block_init(block_state *state, unsigned char *key,
|
||||
int keylen)
|
||||
{
|
||||
char oddkey[8];
|
||||
int i;
|
||||
|
||||
for (i=0; i<8; i++)
|
||||
{
|
||||
oddkey[i]=odd_parity[ key[i] ];
|
||||
}
|
||||
des_set_key((des_cblock *)oddkey, *state);
|
||||
}
|
||||
|
||||
#include "block_template.c"
|
@ -1,688 +0,0 @@
|
||||
|
||||
/*
|
||||
* des.c : Source code for the DES block cipher
|
||||
*
|
||||
* Part of the Python Cryptography Toolkit
|
||||
*
|
||||
* Distribute and use freely; there are no restrictions on further
|
||||
* dissemination and usage except those imposed by the laws of your
|
||||
* country of residence.
|
||||
*
|
||||
*/
|
||||
|
||||
/* des.c */
|
||||
/* Copyright (C) 1993 Eric Young */
|
||||
/* Integrated into the PCT by A.M. Kuchling, November 1994 */
|
||||
/* Fully independent key mode added by Wim Lewis, July 1997 */
|
||||
|
||||
#include "Python.h"
|
||||
|
||||
#define MODULE_NAME DES3
|
||||
#define BLOCK_SIZE 8
|
||||
#define KEY_SIZE 0
|
||||
|
||||
typedef unsigned char des_cblock[8];
|
||||
|
||||
/* ecb_enc.c */
|
||||
/* Copyright (C) 1993 Eric Young - see README for more details */
|
||||
|
||||
#define c2l(c,l) (l =((unsigned long)(*((c)++))) , \
|
||||
l|=((unsigned long)(*((c)++)))<< 8, \
|
||||
l|=((unsigned long)(*((c)++)))<<16, \
|
||||
l|=((unsigned long)(*((c)++)))<<24)
|
||||
|
||||
/* NOTE - c is not incremented as per c2l */
|
||||
#define c2ln(c,l1,l2,n) { \
|
||||
c+=n; \
|
||||
l1=l2=0; \
|
||||
switch (n) { \
|
||||
case 8: l2|=((unsigned long)(*(--(c))))<<24; \
|
||||
case 7: l2|=((unsigned long)(*(--(c))))<<16; \
|
||||
case 6: l2|=((unsigned long)(*(--(c))))<< 8; \
|
||||
case 5: l2|=((unsigned long)(*(--(c)))); \
|
||||
case 4: l1|=((unsigned long)(*(--(c))))<<24; \
|
||||
case 3: l1|=((unsigned long)(*(--(c))))<<16; \
|
||||
case 2: l1|=((unsigned long)(*(--(c))))<< 8; \
|
||||
case 1: l1|=((unsigned long)(*(--(c)))); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
|
||||
*((c)++)=(unsigned char)(((l)>> 8)&0xff), \
|
||||
*((c)++)=(unsigned char)(((l)>>16)&0xff), \
|
||||
*((c)++)=(unsigned char)(((l)>>24)&0xff))
|
||||
|
||||
/* replacements for htonl and ntohl since I have no idea what to do
|
||||
* when faced with machines with 8 byte longs. */
|
||||
#define HDRSIZE 4
|
||||
|
||||
#define n2l(c,l) (l =((unsigned long)(*((c)++)))<<24, \
|
||||
l|=((unsigned long)(*((c)++)))<<16, \
|
||||
l|=((unsigned long)(*((c)++)))<< 8, \
|
||||
l|=((unsigned long)(*((c)++))))
|
||||
|
||||
#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \
|
||||
*((c)++)=(unsigned char)(((l)>>16)&0xff), \
|
||||
*((c)++)=(unsigned char)(((l)>> 8)&0xff), \
|
||||
*((c)++)=(unsigned char)(((l) )&0xff))
|
||||
|
||||
/* NOTE - c is not incremented as per l2c */
|
||||
#define l2cn(l1,l2,c,n) { \
|
||||
c+=n; \
|
||||
switch (n) { \
|
||||
case 8: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \
|
||||
case 7: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \
|
||||
case 6: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \
|
||||
case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \
|
||||
case 4: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \
|
||||
case 3: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \
|
||||
case 2: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \
|
||||
case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define D_ENCRYPT(L,R,S) \
|
||||
u=(R^s[S ]); \
|
||||
t=R^s[S+1]; \
|
||||
t=((t>>4)+(t<<28)); \
|
||||
L^= des_SPtrans[1][(t )&0x3f]| \
|
||||
des_SPtrans[3][(t>> 8)&0x3f]| \
|
||||
des_SPtrans[5][(t>>16)&0x3f]| \
|
||||
des_SPtrans[7][(t>>24)&0x3f]| \
|
||||
des_SPtrans[0][(u )&0x3f]| \
|
||||
des_SPtrans[2][(u>> 8)&0x3f]| \
|
||||
des_SPtrans[4][(u>>16)&0x3f]| \
|
||||
des_SPtrans[6][(u>>24)&0x3f];
|
||||
|
||||
/* IP and FP
|
||||
* The problem is more of a geometric problem that random bit fiddling.
|
||||
0 1 2 3 4 5 6 7 62 54 46 38 30 22 14 6
|
||||
8 9 10 11 12 13 14 15 60 52 44 36 28 20 12 4
|
||||
16 17 18 19 20 21 22 23 58 50 42 34 26 18 10 2
|
||||
24 25 26 27 28 29 30 31 to 56 48 40 32 24 16 8 0
|
||||
|
||||
32 33 34 35 36 37 38 39 63 55 47 39 31 23 15 7
|
||||
40 41 42 43 44 45 46 47 61 53 45 37 29 21 13 5
|
||||
48 49 50 51 52 53 54 55 59 51 43 35 27 19 11 3
|
||||
56 57 58 59 60 61 62 63 57 49 41 33 25 17 9 1
|
||||
|
||||
The output has been subject to swaps of the form
|
||||
0 1 -> 3 1 but the odd and even bits have been put into
|
||||
2 3 2 0
|
||||
different words. The main trick is to remember that
|
||||
t=((l>>size)^r)&(mask);
|
||||
r^=t;
|
||||
l^=(t<<size);
|
||||
can be used to swap and move bits between words.
|
||||
|
||||
So l = 0 1 2 3 r = 16 17 18 19
|
||||
4 5 6 7 20 21 22 23
|
||||
8 9 10 11 24 25 26 27
|
||||
12 13 14 15 28 29 30 31
|
||||
becomes (for size == 2 and mask == 0x3333)
|
||||
t = 2^16 3^17 -- -- l = 0 1 16 17 r = 2 3 18 19
|
||||
6^20 7^21 -- -- 4 5 20 21 6 7 22 23
|
||||
10^24 11^25 -- -- 8 9 24 25 10 11 24 25
|
||||
14^28 15^29 -- -- 12 13 28 29 14 15 28 29
|
||||
|
||||
Thanks for hints from Richard Outerbridge - he told me IP&FP
|
||||
could be done in 15 xor, 10 shifts and 5 ands.
|
||||
When I finally started to think of the problem in 2D
|
||||
I first got ~42 operations without xors. When I remembered
|
||||
how to use xors :-) I got it to its final state.
|
||||
*/
|
||||
#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
|
||||
(b)^=(t),\
|
||||
(a)^=((t)<<(n)))
|
||||
|
||||
|
||||
|
||||
/* spr.h */
|
||||
/* Copyright (C) 1993 Eric Young - see README for more details */
|
||||
static unsigned long des_SPtrans[8][64]={
|
||||
/* nibble 0 */
|
||||
{0x00820200, 0x00020000, 0x80800000, 0x80820200,
|
||||
0x00800000, 0x80020200, 0x80020000, 0x80800000,
|
||||
0x80020200, 0x00820200, 0x00820000, 0x80000200,
|
||||
0x80800200, 0x00800000, 0x00000000, 0x80020000,
|
||||
0x00020000, 0x80000000, 0x00800200, 0x00020200,
|
||||
0x80820200, 0x00820000, 0x80000200, 0x00800200,
|
||||
0x80000000, 0x00000200, 0x00020200, 0x80820000,
|
||||
0x00000200, 0x80800200, 0x80820000, 0x00000000,
|
||||
0x00000000, 0x80820200, 0x00800200, 0x80020000,
|
||||
0x00820200, 0x00020000, 0x80000200, 0x00800200,
|
||||
0x80820000, 0x00000200, 0x00020200, 0x80800000,
|
||||
0x80020200, 0x80000000, 0x80800000, 0x00820000,
|
||||
0x80820200, 0x00020200, 0x00820000, 0x80800200,
|
||||
0x00800000, 0x80000200, 0x80020000, 0x00000000,
|
||||
0x00020000, 0x00800000, 0x80800200, 0x00820200,
|
||||
0x80000000, 0x80820000, 0x00000200, 0x80020200},
|
||||
|
||||
/* nibble 1 */
|
||||
{0x10042004, 0x00000000, 0x00042000, 0x10040000,
|
||||
0x10000004, 0x00002004, 0x10002000, 0x00042000,
|
||||
0x00002000, 0x10040004, 0x00000004, 0x10002000,
|
||||
0x00040004, 0x10042000, 0x10040000, 0x00000004,
|
||||
0x00040000, 0x10002004, 0x10040004, 0x00002000,
|
||||
0x00042004, 0x10000000, 0x00000000, 0x00040004,
|
||||
0x10002004, 0x00042004, 0x10042000, 0x10000004,
|
||||
0x10000000, 0x00040000, 0x00002004, 0x10042004,
|
||||
0x00040004, 0x10042000, 0x10002000, 0x00042004,
|
||||
0x10042004, 0x00040004, 0x10000004, 0x00000000,
|
||||
0x10000000, 0x00002004, 0x00040000, 0x10040004,
|
||||
0x00002000, 0x10000000, 0x00042004, 0x10002004,
|
||||
0x10042000, 0x00002000, 0x00000000, 0x10000004,
|
||||
0x00000004, 0x10042004, 0x00042000, 0x10040000,
|
||||
0x10040004, 0x00040000, 0x00002004, 0x10002000,
|
||||
0x10002004, 0x00000004, 0x10040000, 0x00042000},
|
||||
|
||||
/* nibble 2 */
|
||||
{0x41000000, 0x01010040, 0x00000040, 0x41000040,
|
||||
0x40010000, 0x01000000, 0x41000040, 0x00010040,
|
||||
0x01000040, 0x00010000, 0x01010000, 0x40000000,
|
||||
0x41010040, 0x40000040, 0x40000000, 0x41010000,
|
||||
0x00000000, 0x40010000, 0x01010040, 0x00000040,
|
||||
0x40000040, 0x41010040, 0x00010000, 0x41000000,
|
||||
0x41010000, 0x01000040, 0x40010040, 0x01010000,
|
||||
0x00010040, 0x00000000, 0x01000000, 0x40010040,
|
||||
0x01010040, 0x00000040, 0x40000000, 0x00010000,
|
||||
0x40000040, 0x40010000, 0x01010000, 0x41000040,
|
||||
0x00000000, 0x01010040, 0x00010040, 0x41010000,
|
||||
0x40010000, 0x01000000, 0x41010040, 0x40000000,
|
||||
0x40010040, 0x41000000, 0x01000000, 0x41010040,
|
||||
0x00010000, 0x01000040, 0x41000040, 0x00010040,
|
||||
0x01000040, 0x00000000, 0x41010000, 0x40000040,
|
||||
0x41000000, 0x40010040, 0x00000040, 0x01010000},
|
||||
|
||||
/* nibble 3 */
|
||||
{0x00100402, 0x04000400, 0x00000002, 0x04100402,
|
||||
0x00000000, 0x04100000, 0x04000402, 0x00100002,
|
||||
0x04100400, 0x04000002, 0x04000000, 0x00000402,
|
||||
0x04000002, 0x00100402, 0x00100000, 0x04000000,
|
||||
0x04100002, 0x00100400, 0x00000400, 0x00000002,
|
||||
0x00100400, 0x04000402, 0x04100000, 0x00000400,
|
||||
0x00000402, 0x00000000, 0x00100002, 0x04100400,
|
||||
0x04000400, 0x04100002, 0x04100402, 0x00100000,
|
||||
0x04100002, 0x00000402, 0x00100000, 0x04000002,
|
||||
0x00100400, 0x04000400, 0x00000002, 0x04100000,
|
||||
0x04000402, 0x00000000, 0x00000400, 0x00100002,
|
||||
0x00000000, 0x04100002, 0x04100400, 0x00000400,
|
||||
0x04000000, 0x04100402, 0x00100402, 0x00100000,
|
||||
0x04100402, 0x00000002, 0x04000400, 0x00100402,
|
||||
0x00100002, 0x00100400, 0x04100000, 0x04000402,
|
||||
0x00000402, 0x04000000, 0x04000002, 0x04100400},
|
||||
|
||||
/* nibble 4 */
|
||||
{0x02000000, 0x00004000, 0x00000100, 0x02004108,
|
||||
0x02004008, 0x02000100, 0x00004108, 0x02004000,
|
||||
0x00004000, 0x00000008, 0x02000008, 0x00004100,
|
||||
0x02000108, 0x02004008, 0x02004100, 0x00000000,
|
||||
0x00004100, 0x02000000, 0x00004008, 0x00000108,
|
||||
0x02000100, 0x00004108, 0x00000000, 0x02000008,
|
||||
0x00000008, 0x02000108, 0x02004108, 0x00004008,
|
||||
0x02004000, 0x00000100, 0x00000108, 0x02004100,
|
||||
0x02004100, 0x02000108, 0x00004008, 0x02004000,
|
||||
0x00004000, 0x00000008, 0x02000008, 0x02000100,
|
||||
0x02000000, 0x00004100, 0x02004108, 0x00000000,
|
||||
0x00004108, 0x02000000, 0x00000100, 0x00004008,
|
||||
0x02000108, 0x00000100, 0x00000000, 0x02004108,
|
||||
0x02004008, 0x02004100, 0x00000108, 0x00004000,
|
||||
0x00004100, 0x02004008, 0x02000100, 0x00000108,
|
||||
0x00000008, 0x00004108, 0x02004000, 0x02000008},
|
||||
|
||||
/* nibble 5 */
|
||||
{0x20000010, 0x00080010, 0x00000000, 0x20080800,
|
||||
0x00080010, 0x00000800, 0x20000810, 0x00080000,
|
||||
0x00000810, 0x20080810, 0x00080800, 0x20000000,
|
||||
0x20000800, 0x20000010, 0x20080000, 0x00080810,
|
||||
0x00080000, 0x20000810, 0x20080010, 0x00000000,
|
||||
0x00000800, 0x00000010, 0x20080800, 0x20080010,
|
||||
0x20080810, 0x20080000, 0x20000000, 0x00000810,
|
||||
0x00000010, 0x00080800, 0x00080810, 0x20000800,
|
||||
0x00000810, 0x20000000, 0x20000800, 0x00080810,
|
||||
0x20080800, 0x00080010, 0x00000000, 0x20000800,
|
||||
0x20000000, 0x00000800, 0x20080010, 0x00080000,
|
||||
0x00080010, 0x20080810, 0x00080800, 0x00000010,
|
||||
0x20080810, 0x00080800, 0x00080000, 0x20000810,
|
||||
0x20000010, 0x20080000, 0x00080810, 0x00000000,
|
||||
0x00000800, 0x20000010, 0x20000810, 0x20080800,
|
||||
0x20080000, 0x00000810, 0x00000010, 0x20080010},
|
||||
|
||||
/* nibble 6 */
|
||||
{0x00001000, 0x00000080, 0x00400080, 0x00400001,
|
||||
0x00401081, 0x00001001, 0x00001080, 0x00000000,
|
||||
0x00400000, 0x00400081, 0x00000081, 0x00401000,
|
||||
0x00000001, 0x00401080, 0x00401000, 0x00000081,
|
||||
0x00400081, 0x00001000, 0x00001001, 0x00401081,
|
||||
0x00000000, 0x00400080, 0x00400001, 0x00001080,
|
||||
0x00401001, 0x00001081, 0x00401080, 0x00000001,
|
||||
0x00001081, 0x00401001, 0x00000080, 0x00400000,
|
||||
0x00001081, 0x00401000, 0x00401001, 0x00000081,
|
||||
0x00001000, 0x00000080, 0x00400000, 0x00401001,
|
||||
0x00400081, 0x00001081, 0x00001080, 0x00000000,
|
||||
0x00000080, 0x00400001, 0x00000001, 0x00400080,
|
||||
0x00000000, 0x00400081, 0x00400080, 0x00001080,
|
||||
0x00000081, 0x00001000, 0x00401081, 0x00400000,
|
||||
0x00401080, 0x00000001, 0x00001001, 0x00401081,
|
||||
0x00400001, 0x00401080, 0x00401000, 0x00001001},
|
||||
|
||||
/* nibble 7 */
|
||||
{0x08200020, 0x08208000, 0x00008020, 0x00000000,
|
||||
0x08008000, 0x00200020, 0x08200000, 0x08208020,
|
||||
0x00000020, 0x08000000, 0x00208000, 0x00008020,
|
||||
0x00208020, 0x08008020, 0x08000020, 0x08200000,
|
||||
0x00008000, 0x00208020, 0x00200020, 0x08008000,
|
||||
0x08208020, 0x08000020, 0x00000000, 0x00208000,
|
||||
0x08000000, 0x00200000, 0x08008020, 0x08200020,
|
||||
0x00200000, 0x00008000, 0x08208000, 0x00000020,
|
||||
0x00200000, 0x00008000, 0x08000020, 0x08208020,
|
||||
0x00008020, 0x08000000, 0x00000000, 0x00208000,
|
||||
0x08200020, 0x08008020, 0x08008000, 0x00200020,
|
||||
0x08208000, 0x00000020, 0x00200020, 0x08008000,
|
||||
0x08208020, 0x00200000, 0x08200000, 0x08000020,
|
||||
0x00208000, 0x00008020, 0x08008020, 0x08200000,
|
||||
0x00000020, 0x08208000, 0x00208020, 0x00000000,
|
||||
0x08000000, 0x08200020, 0x00008000, 0x00208020}};
|
||||
|
||||
static unsigned long des_skb[8][64]={
|
||||
/* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
|
||||
{0x00000000,0x00000010,0x20000000,0x20000010,
|
||||
0x00010000,0x00010010,0x20010000,0x20010010,
|
||||
0x00000800,0x00000810,0x20000800,0x20000810,
|
||||
0x00010800,0x00010810,0x20010800,0x20010810,
|
||||
0x00000020,0x00000030,0x20000020,0x20000030,
|
||||
0x00010020,0x00010030,0x20010020,0x20010030,
|
||||
0x00000820,0x00000830,0x20000820,0x20000830,
|
||||
0x00010820,0x00010830,0x20010820,0x20010830,
|
||||
0x00080000,0x00080010,0x20080000,0x20080010,
|
||||
0x00090000,0x00090010,0x20090000,0x20090010,
|
||||
0x00080800,0x00080810,0x20080800,0x20080810,
|
||||
0x00090800,0x00090810,0x20090800,0x20090810,
|
||||
0x00080020,0x00080030,0x20080020,0x20080030,
|
||||
0x00090020,0x00090030,0x20090020,0x20090030,
|
||||
0x00080820,0x00080830,0x20080820,0x20080830,
|
||||
0x00090820,0x00090830,0x20090820,0x20090830},
|
||||
/* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
|
||||
{0x00000000,0x02000000,0x00002000,0x02002000,
|
||||
0x00200000,0x02200000,0x00202000,0x02202000,
|
||||
0x00000004,0x02000004,0x00002004,0x02002004,
|
||||
0x00200004,0x02200004,0x00202004,0x02202004,
|
||||
0x00000400,0x02000400,0x00002400,0x02002400,
|
||||
0x00200400,0x02200400,0x00202400,0x02202400,
|
||||
0x00000404,0x02000404,0x00002404,0x02002404,
|
||||
0x00200404,0x02200404,0x00202404,0x02202404,
|
||||
0x10000000,0x12000000,0x10002000,0x12002000,
|
||||
0x10200000,0x12200000,0x10202000,0x12202000,
|
||||
0x10000004,0x12000004,0x10002004,0x12002004,
|
||||
0x10200004,0x12200004,0x10202004,0x12202004,
|
||||
0x10000400,0x12000400,0x10002400,0x12002400,
|
||||
0x10200400,0x12200400,0x10202400,0x12202400,
|
||||
0x10000404,0x12000404,0x10002404,0x12002404,
|
||||
0x10200404,0x12200404,0x10202404,0x12202404},
|
||||
/* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
|
||||
{0x00000000,0x00000001,0x00040000,0x00040001,
|
||||
0x01000000,0x01000001,0x01040000,0x01040001,
|
||||
0x00000002,0x00000003,0x00040002,0x00040003,
|
||||
0x01000002,0x01000003,0x01040002,0x01040003,
|
||||
0x00000200,0x00000201,0x00040200,0x00040201,
|
||||
0x01000200,0x01000201,0x01040200,0x01040201,
|
||||
0x00000202,0x00000203,0x00040202,0x00040203,
|
||||
0x01000202,0x01000203,0x01040202,0x01040203,
|
||||
0x08000000,0x08000001,0x08040000,0x08040001,
|
||||
0x09000000,0x09000001,0x09040000,0x09040001,
|
||||
0x08000002,0x08000003,0x08040002,0x08040003,
|
||||
0x09000002,0x09000003,0x09040002,0x09040003,
|
||||
0x08000200,0x08000201,0x08040200,0x08040201,
|
||||
0x09000200,0x09000201,0x09040200,0x09040201,
|
||||
0x08000202,0x08000203,0x08040202,0x08040203,
|
||||
0x09000202,0x09000203,0x09040202,0x09040203},
|
||||
/* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
|
||||
{0x00000000,0x00100000,0x00000100,0x00100100,
|
||||
0x00000008,0x00100008,0x00000108,0x00100108,
|
||||
0x00001000,0x00101000,0x00001100,0x00101100,
|
||||
0x00001008,0x00101008,0x00001108,0x00101108,
|
||||
0x04000000,0x04100000,0x04000100,0x04100100,
|
||||
0x04000008,0x04100008,0x04000108,0x04100108,
|
||||
0x04001000,0x04101000,0x04001100,0x04101100,
|
||||
0x04001008,0x04101008,0x04001108,0x04101108,
|
||||
0x00020000,0x00120000,0x00020100,0x00120100,
|
||||
0x00020008,0x00120008,0x00020108,0x00120108,
|
||||
0x00021000,0x00121000,0x00021100,0x00121100,
|
||||
0x00021008,0x00121008,0x00021108,0x00121108,
|
||||
0x04020000,0x04120000,0x04020100,0x04120100,
|
||||
0x04020008,0x04120008,0x04020108,0x04120108,
|
||||
0x04021000,0x04121000,0x04021100,0x04121100,
|
||||
0x04021008,0x04121008,0x04021108,0x04121108},
|
||||
/* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
|
||||
{0x00000000,0x10000000,0x00010000,0x10010000,
|
||||
0x00000004,0x10000004,0x00010004,0x10010004,
|
||||
0x20000000,0x30000000,0x20010000,0x30010000,
|
||||
0x20000004,0x30000004,0x20010004,0x30010004,
|
||||
0x00100000,0x10100000,0x00110000,0x10110000,
|
||||
0x00100004,0x10100004,0x00110004,0x10110004,
|
||||
0x20100000,0x30100000,0x20110000,0x30110000,
|
||||
0x20100004,0x30100004,0x20110004,0x30110004,
|
||||
0x00001000,0x10001000,0x00011000,0x10011000,
|
||||
0x00001004,0x10001004,0x00011004,0x10011004,
|
||||
0x20001000,0x30001000,0x20011000,0x30011000,
|
||||
0x20001004,0x30001004,0x20011004,0x30011004,
|
||||
0x00101000,0x10101000,0x00111000,0x10111000,
|
||||
0x00101004,0x10101004,0x00111004,0x10111004,
|
||||
0x20101000,0x30101000,0x20111000,0x30111000,
|
||||
0x20101004,0x30101004,0x20111004,0x30111004},
|
||||
/* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
|
||||
{0x00000000,0x08000000,0x00000008,0x08000008,
|
||||
0x00000400,0x08000400,0x00000408,0x08000408,
|
||||
0x00020000,0x08020000,0x00020008,0x08020008,
|
||||
0x00020400,0x08020400,0x00020408,0x08020408,
|
||||
0x00000001,0x08000001,0x00000009,0x08000009,
|
||||
0x00000401,0x08000401,0x00000409,0x08000409,
|
||||
0x00020001,0x08020001,0x00020009,0x08020009,
|
||||
0x00020401,0x08020401,0x00020409,0x08020409,
|
||||
0x02000000,0x0A000000,0x02000008,0x0A000008,
|
||||
0x02000400,0x0A000400,0x02000408,0x0A000408,
|
||||
0x02020000,0x0A020000,0x02020008,0x0A020008,
|
||||
0x02020400,0x0A020400,0x02020408,0x0A020408,
|
||||
0x02000001,0x0A000001,0x02000009,0x0A000009,
|
||||
0x02000401,0x0A000401,0x02000409,0x0A000409,
|
||||
0x02020001,0x0A020001,0x02020009,0x0A020009,
|
||||
0x02020401,0x0A020401,0x02020409,0x0A020409},
|
||||
/* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
|
||||
{0x00000000,0x00000100,0x00080000,0x00080100,
|
||||
0x01000000,0x01000100,0x01080000,0x01080100,
|
||||
0x00000010,0x00000110,0x00080010,0x00080110,
|
||||
0x01000010,0x01000110,0x01080010,0x01080110,
|
||||
0x00200000,0x00200100,0x00280000,0x00280100,
|
||||
0x01200000,0x01200100,0x01280000,0x01280100,
|
||||
0x00200010,0x00200110,0x00280010,0x00280110,
|
||||
0x01200010,0x01200110,0x01280010,0x01280110,
|
||||
0x00000200,0x00000300,0x00080200,0x00080300,
|
||||
0x01000200,0x01000300,0x01080200,0x01080300,
|
||||
0x00000210,0x00000310,0x00080210,0x00080310,
|
||||
0x01000210,0x01000310,0x01080210,0x01080310,
|
||||
0x00200200,0x00200300,0x00280200,0x00280300,
|
||||
0x01200200,0x01200300,0x01280200,0x01280300,
|
||||
0x00200210,0x00200310,0x00280210,0x00280310,
|
||||
0x01200210,0x01200310,0x01280210,0x01280310},
|
||||
/* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
|
||||
{0x00000000,0x04000000,0x00040000,0x04040000,
|
||||
0x00000002,0x04000002,0x00040002,0x04040002,
|
||||
0x00002000,0x04002000,0x00042000,0x04042000,
|
||||
0x00002002,0x04002002,0x00042002,0x04042002,
|
||||
0x00000020,0x04000020,0x00040020,0x04040020,
|
||||
0x00000022,0x04000022,0x00040022,0x04040022,
|
||||
0x00002020,0x04002020,0x00042020,0x04042020,
|
||||
0x00002022,0x04002022,0x00042022,0x04042022,
|
||||
0x00000800,0x04000800,0x00040800,0x04040800,
|
||||
0x00000802,0x04000802,0x00040802,0x04040802,
|
||||
0x00002800,0x04002800,0x00042800,0x04042800,
|
||||
0x00002802,0x04002802,0x00042802,0x04042802,
|
||||
0x00000820,0x04000820,0x00040820,0x04040820,
|
||||
0x00000822,0x04000822,0x00040822,0x04040822,
|
||||
0x00002820,0x04002820,0x00042820,0x04042820,
|
||||
0x00002822,0x04002822,0x00042822,0x04042822}
|
||||
};
|
||||
|
||||
typedef struct des_ks_struct
|
||||
{
|
||||
union {
|
||||
des_cblock _;
|
||||
/* make sure things are correct size on machines with
|
||||
* 8 byte longs */
|
||||
unsigned long pad[2];
|
||||
} ks;
|
||||
#define _ ks._
|
||||
} des_key_schedule[16];
|
||||
|
||||
typedef struct
|
||||
{
|
||||
des_key_schedule KeySched1, KeySched2, KeySched3;
|
||||
} block_state;
|
||||
|
||||
static int des_encrypt(unsigned long *input, unsigned long *output,
|
||||
des_key_schedule ks, int encrypt)
|
||||
{
|
||||
register unsigned long l,r,t,u;
|
||||
register int i;
|
||||
register unsigned long *s;
|
||||
|
||||
l=input[0];
|
||||
r=input[1];
|
||||
|
||||
/* do IP */
|
||||
PERM_OP(r,l,t, 4,0x0f0f0f0f);
|
||||
PERM_OP(l,r,t,16,0x0000ffff);
|
||||
PERM_OP(r,l,t, 2,0x33333333);
|
||||
PERM_OP(l,r,t, 8,0x00ff00ff);
|
||||
PERM_OP(r,l,t, 1,0x55555555);
|
||||
/* r and l are reversed - remember that :-) - fix
|
||||
* it in the next step */
|
||||
|
||||
/* Things have been modified so that the initial rotate is
|
||||
* done outside the loop. This required the
|
||||
* des_SPtrans values in sp.h to be rotated 1 bit to the right.
|
||||
* One perl script later and things have a 5% speed up on a sparc2.
|
||||
* Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
|
||||
* for pointing this out. */
|
||||
t=(r<<1)|(r>>31);
|
||||
r=(l<<1)|(l>>31);
|
||||
l=t;
|
||||
|
||||
/* clear the top bits on machines with 8byte longs */
|
||||
l&=0xffffffff;
|
||||
r&=0xffffffff;
|
||||
|
||||
s=(unsigned long *)ks;
|
||||
/* I don't know if it is worth the effort of loop unrolling the
|
||||
* inner loop */
|
||||
if (encrypt)
|
||||
{
|
||||
for (i=0; i<32; i+=4)
|
||||
{
|
||||
D_ENCRYPT(l,r,i+0); /* 1 */
|
||||
D_ENCRYPT(r,l,i+2); /* 2 */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=30; i>0; i-=4)
|
||||
{
|
||||
D_ENCRYPT(l,r,i-0); /* 16 */
|
||||
D_ENCRYPT(r,l,i-2); /* 15 */
|
||||
}
|
||||
}
|
||||
l=(l>>1)|(l<<31);
|
||||
r=(r>>1)|(r<<31);
|
||||
/* clear the top bits on machines with 8byte longs */
|
||||
l&=0xffffffff;
|
||||
r&=0xffffffff;
|
||||
|
||||
/* swap l and r
|
||||
* we will not do the swap so just remember they are
|
||||
* reversed for the rest of the subroutine
|
||||
* luckily FP fixes this problem :-) */
|
||||
|
||||
PERM_OP(r,l,t, 1,0x55555555);
|
||||
PERM_OP(l,r,t, 8,0x00ff00ff);
|
||||
PERM_OP(r,l,t, 2,0x33333333);
|
||||
PERM_OP(l,r,t,16,0x0000ffff);
|
||||
PERM_OP(r,l,t, 4,0x0f0f0f0f);
|
||||
|
||||
output[0]=l;
|
||||
output[1]=r;
|
||||
l=r=t=u=0;
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int des_ecb_encrypt(des_cblock *input, des_cblock *output,
|
||||
des_key_schedule ks, int encrypt)
|
||||
{
|
||||
register unsigned long l0,l1;
|
||||
register unsigned char *in,*out;
|
||||
unsigned long ll[2];
|
||||
|
||||
in=(unsigned char *)input;
|
||||
out=(unsigned char *)output;
|
||||
c2l(in,l0);
|
||||
c2l(in,l1);
|
||||
ll[0]=l0;
|
||||
ll[1]=l1;
|
||||
des_encrypt(ll,ll,ks,encrypt);
|
||||
l0=ll[0];
|
||||
l1=ll[1];
|
||||
l2c(l0,out);
|
||||
l2c(l1,out);
|
||||
l0=l1=ll[0]=ll[1]=0;
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void block_decrypt(block_state *self,
|
||||
unsigned char *in,
|
||||
unsigned char *out)
|
||||
{
|
||||
des_cblock output, output2;
|
||||
|
||||
des_ecb_encrypt((des_cblock *)in, &output, self->KeySched3, 0);
|
||||
des_ecb_encrypt(&output, &output2, self->KeySched2, 1);
|
||||
des_ecb_encrypt(&output2, (des_cblock *)out, self->KeySched1, 0);
|
||||
}
|
||||
|
||||
static void block_encrypt(block_state *self,
|
||||
unsigned char *in,
|
||||
unsigned char *out)
|
||||
{
|
||||
des_cblock output, output2;
|
||||
|
||||
des_ecb_encrypt((des_cblock *)in, &output, self->KeySched1, 1);
|
||||
des_ecb_encrypt(&output, &output2, self->KeySched2, 0);
|
||||
des_ecb_encrypt(&output2, (des_cblock *)out, self->KeySched3, 1);
|
||||
}
|
||||
|
||||
/* NOW DEFINED IN des_local.h
|
||||
* See ecb_encrypt.c for a pseudo description of these macros.
|
||||
* #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
|
||||
* (b)^=(t),\
|
||||
* (a)=((a)^((t)<<(n))))
|
||||
*/
|
||||
|
||||
#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
|
||||
(a)=(a)^(t)^(t>>(16-(n))))
|
||||
|
||||
static char shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0};
|
||||
|
||||
static int des_set_key(des_cblock *key, des_key_schedule schedule)
|
||||
{
|
||||
register unsigned long c,d,t,s;
|
||||
register unsigned char *in;
|
||||
register unsigned long *k;
|
||||
register int i;
|
||||
|
||||
k=(unsigned long *)schedule;
|
||||
in=(unsigned char *)key;
|
||||
|
||||
c2l(in,c);
|
||||
c2l(in,d);
|
||||
|
||||
/* do PC1 in 60 simple operations */
|
||||
/* PERM_OP(d,c,t,4,0x0f0f0f0f);
|
||||
HPERM_OP(c,t,-2, 0xcccc0000);
|
||||
HPERM_OP(c,t,-1, 0xaaaa0000);
|
||||
HPERM_OP(c,t, 8, 0x00ff0000);
|
||||
HPERM_OP(c,t,-1, 0xaaaa0000);
|
||||
HPERM_OP(d,t,-8, 0xff000000);
|
||||
HPERM_OP(d,t, 8, 0x00ff0000);
|
||||
HPERM_OP(d,t, 2, 0x33330000);
|
||||
d=((d&0x00aa00aa)<<7)|((d&0x55005500)>>7)|(d&0xaa55aa55);
|
||||
d=(d>>8)|((c&0xf0000000)>>4);
|
||||
c&=0x0fffffff; */
|
||||
|
||||
/* I now do it in 47 simple operations :-)
|
||||
* Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
|
||||
* for the inspiration. :-) */
|
||||
PERM_OP (d,c,t,4,0x0f0f0f0f);
|
||||
HPERM_OP(c,t,-2,0xcccc0000);
|
||||
HPERM_OP(d,t,-2,0xcccc0000);
|
||||
PERM_OP (d,c,t,1,0x55555555);
|
||||
PERM_OP (c,d,t,8,0x00ff00ff);
|
||||
PERM_OP (d,c,t,1,0x55555555);
|
||||
d= (((d&0x000000ff)<<16)| (d&0x0000ff00) |
|
||||
((d&0x00ff0000)>>16)|((c&0xf0000000)>>4));
|
||||
c&=0x0fffffff;
|
||||
|
||||
for (i=0; i<16; i++)
|
||||
{
|
||||
if (shifts2[i])
|
||||
{ c=((c>>2)|(c<<26)); d=((d>>2)|(d<<26)); }
|
||||
else
|
||||
{ c=((c>>1)|(c<<27)); d=((d>>1)|(d<<27)); }
|
||||
c&=0x0fffffff;
|
||||
d&=0x0fffffff;
|
||||
/* could be a few less shifts but I am to lazy at this
|
||||
* point in time to investigate */
|
||||
s= des_skb[0][ (c )&0x3f ]|
|
||||
des_skb[1][((c>> 6)&0x03)|((c>> 7)&0x3c)]|
|
||||
des_skb[2][((c>>13)&0x0f)|((c>>14)&0x30)]|
|
||||
des_skb[3][((c>>20)&0x01)|((c>>21)&0x06) |
|
||||
((c>>22)&0x38)];
|
||||
t= des_skb[4][ (d )&0x3f ]|
|
||||
des_skb[5][((d>> 7)&0x03)|((d>> 8)&0x3c)]|
|
||||
des_skb[6][ (d>>15)&0x3f ]|
|
||||
des_skb[7][((d>>21)&0x0f)|((d>>22)&0x30)];
|
||||
|
||||
/* table contained 0213 4657 */
|
||||
*(k++)=((t<<16)|(s&0x0000ffff))&0xffffffff;
|
||||
s= ((s>>16)|(t&0xffff0000));
|
||||
|
||||
s=(s<<4)|(s>>28);
|
||||
*(k++)=s&0xffffffff;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
static const unsigned char odd_parity[256]={
|
||||
1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14,
|
||||
16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
|
||||
32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
|
||||
49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
|
||||
64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
|
||||
81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
|
||||
97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110,
|
||||
112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127,
|
||||
128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143,
|
||||
145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158,
|
||||
161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174,
|
||||
176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191,
|
||||
193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206,
|
||||
208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223,
|
||||
224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239,
|
||||
241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254};
|
||||
|
||||
static void block_init(block_state *self, unsigned char *key,
|
||||
int keylength)
|
||||
{
|
||||
char oddkey[24];
|
||||
int i;
|
||||
|
||||
if (keylength != 16 && keylength != 24) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"DES3 key must be either 16 or 24 bytes long");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i=0; i<keylength; i++)
|
||||
{
|
||||
oddkey[i]=odd_parity[ key[i] ];
|
||||
}
|
||||
des_set_key((des_cblock *)(oddkey+0), self->KeySched1);
|
||||
des_set_key((des_cblock *)(oddkey+8), self->KeySched2);
|
||||
if (keylength == 24) {
|
||||
des_set_key((des_cblock *)(oddkey+16), self->KeySched3);
|
||||
} else {
|
||||
memcpy(self->KeySched3, self->KeySched1,
|
||||
sizeof(self->KeySched3));
|
||||
}
|
||||
}
|
||||
|
||||
#include "block_template.c"
|
@ -1,118 +0,0 @@
|
||||
|
||||
/*
|
||||
* md2.c : MD2 hash algorithm.
|
||||
*
|
||||
* Part of the Python Cryptography Toolkit
|
||||
*
|
||||
* Distribute and use freely; there are no restrictions on further
|
||||
* dissemination and usage except those imposed by the laws of your
|
||||
* country of residence.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include "Python.h"
|
||||
|
||||
#define MODULE_NAME MD2
|
||||
#define DIGEST_SIZE 16
|
||||
|
||||
typedef unsigned char U8;
|
||||
typedef unsigned int U32;
|
||||
|
||||
typedef struct {
|
||||
U8 C[16], X[48];
|
||||
int count;
|
||||
U8 buf[16];
|
||||
} hash_state;
|
||||
|
||||
static void hash_init (hash_state *ptr)
|
||||
{
|
||||
memset(ptr->X, 0, 48);
|
||||
memset(ptr->C, 0, 16);
|
||||
ptr->count=0;
|
||||
}
|
||||
|
||||
static U8 S[256] = {
|
||||
41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6,
|
||||
19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188,
|
||||
76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24,
|
||||
138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251,
|
||||
245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63,
|
||||
148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50,
|
||||
39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165,
|
||||
181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210,
|
||||
150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157,
|
||||
112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27,
|
||||
96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
|
||||
85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197,
|
||||
234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65,
|
||||
129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123,
|
||||
8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233,
|
||||
203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228,
|
||||
166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237,
|
||||
31, 26, 219, 153, 141, 51, 159, 17, 131, 20
|
||||
};
|
||||
|
||||
static void
|
||||
hash_copy(hash_state *src, hash_state *dest)
|
||||
{
|
||||
dest->count=src->count;
|
||||
memcpy(dest->buf, src->buf, dest->count);
|
||||
memcpy(dest->X, src->X, 48);
|
||||
memcpy(dest->C, src->C, 16);
|
||||
}
|
||||
|
||||
|
||||
static void hash_update (hash_state *self, const U8 *buf, U32 len)
|
||||
{
|
||||
U32 L;
|
||||
while (len)
|
||||
{
|
||||
L=(16-self->count) < len ? (16-self->count) : len;
|
||||
memcpy(self->buf+self->count, buf, L);
|
||||
self->count+=L;
|
||||
buf+=L;
|
||||
len-=L;
|
||||
if (self->count==16)
|
||||
{
|
||||
U8 t;
|
||||
int i,j;
|
||||
|
||||
self->count=0;
|
||||
memcpy(self->X+16, self->buf, 16);
|
||||
t=self->C[15];
|
||||
for(i=0; i<16; i++)
|
||||
{
|
||||
self->X[32+i]=self->X[16+i]^self->X[i];
|
||||
t=self->C[i]^=S[self->buf[i]^t];
|
||||
}
|
||||
|
||||
t=0;
|
||||
for(i=0; i<18; i++)
|
||||
{
|
||||
for(j=0; j<48; j++)
|
||||
t=self->X[j]^=S[t];
|
||||
t=(t+i) & 0xFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
hash_digest (const hash_state *self)
|
||||
{
|
||||
U8 padding[16];
|
||||
U32 padlen;
|
||||
hash_state temp;
|
||||
int i;
|
||||
|
||||
memcpy(&temp, self, sizeof(hash_state));
|
||||
padlen= 16-self->count;
|
||||
for(i=0; i<padlen; i++) padding[i]=padlen;
|
||||
hash_update(&temp, padding, padlen);
|
||||
hash_update(&temp, temp.C, 16);
|
||||
return PyString_FromStringAndSize(temp.X, 16);
|
||||
}
|
||||
|
||||
#include "hash_template.c"
|
@ -1,203 +0,0 @@
|
||||
|
||||
/*
|
||||
* md4.c : MD4 hash algorithm.
|
||||
*
|
||||
* Part of the Python Cryptography Toolkit
|
||||
*
|
||||
* Distribute and use freely; there are no restrictions on further
|
||||
* dissemination and usage except those imposed by the laws of your
|
||||
* country of residence.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include <Python.h>
|
||||
|
||||
#define MODULE_NAME MD4
|
||||
#define DIGEST_SIZE 16
|
||||
|
||||
typedef unsigned int U32;
|
||||
typedef unsigned char U8;
|
||||
#define U32_MAX (U32)4294967295
|
||||
|
||||
typedef struct {
|
||||
U32 A,B,C,D, count;
|
||||
U32 len1, len2;
|
||||
U8 buf[64];
|
||||
} hash_state;
|
||||
|
||||
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
|
||||
#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
|
||||
#define H(x, y, z) ((x) ^ (y) ^ (z))
|
||||
|
||||
/* ROTATE_LEFT rotates x left n bits */
|
||||
#define ROL(x, n) (((x) << n) | ((x) >> (32-n) ))
|
||||
|
||||
static void
|
||||
hash_init (hash_state *ptr)
|
||||
{
|
||||
ptr->A=(U32)0x67452301;
|
||||
ptr->B=(U32)0xefcdab89;
|
||||
ptr->C=(U32)0x98badcfe;
|
||||
ptr->D=(U32)0x10325476;
|
||||
ptr->count=ptr->len1=ptr->len2=0;
|
||||
}
|
||||
|
||||
static void
|
||||
hash_copy(hash_state *src, hash_state *dest)
|
||||
{
|
||||
dest->len1=src->len1;
|
||||
dest->len2=src->len2;
|
||||
dest->A=src->A;
|
||||
dest->B=src->B;
|
||||
dest->C=src->C;
|
||||
dest->D=src->D;
|
||||
dest->count=src->count;
|
||||
memcpy(dest->buf, src->buf, dest->count);
|
||||
}
|
||||
|
||||
static void
|
||||
hash_update (hash_state *self, const U8 *buf, U32 len)
|
||||
{
|
||||
U32 L;
|
||||
|
||||
if ((self->len1+(len<<3))<self->len1)
|
||||
{
|
||||
self->len2++;
|
||||
}
|
||||
self->len1+=len<< 3;
|
||||
self->len2+=len>>29;
|
||||
while (len>0)
|
||||
{
|
||||
L=(64-self->count) < len ? (64-self->count) : len;
|
||||
memcpy(self->buf+self->count, buf, L);
|
||||
self->count+=L;
|
||||
buf+=L;
|
||||
len-=L;
|
||||
if (self->count==64)
|
||||
{
|
||||
U32 X[16], A, B, C, D;
|
||||
int i,j;
|
||||
self->count=0;
|
||||
for(i=j=0; j<16; i+=4, j++)
|
||||
X[j]=((U32)self->buf[i] + ((U32)self->buf[i+1]<<8) +
|
||||
((U32)self->buf[i+2]<<16) + ((U32)self->buf[i+3]<<24));
|
||||
|
||||
|
||||
A=self->A; B=self->B; C=self->C; D=self->D;
|
||||
|
||||
#define function(a,b,c,d,k,s) a=ROL(a+F(b,c,d)+X[k],s);
|
||||
function(A,B,C,D, 0, 3);
|
||||
function(D,A,B,C, 1, 7);
|
||||
function(C,D,A,B, 2,11);
|
||||
function(B,C,D,A, 3,19);
|
||||
function(A,B,C,D, 4, 3);
|
||||
function(D,A,B,C, 5, 7);
|
||||
function(C,D,A,B, 6,11);
|
||||
function(B,C,D,A, 7,19);
|
||||
function(A,B,C,D, 8, 3);
|
||||
function(D,A,B,C, 9, 7);
|
||||
function(C,D,A,B,10,11);
|
||||
function(B,C,D,A,11,19);
|
||||
function(A,B,C,D,12, 3);
|
||||
function(D,A,B,C,13, 7);
|
||||
function(C,D,A,B,14,11);
|
||||
function(B,C,D,A,15,19);
|
||||
|
||||
#undef function
|
||||
#define function(a,b,c,d,k,s) a=ROL(a+G(b,c,d)+X[k]+(U32)0x5a827999,s);
|
||||
function(A,B,C,D, 0, 3);
|
||||
function(D,A,B,C, 4, 5);
|
||||
function(C,D,A,B, 8, 9);
|
||||
function(B,C,D,A,12,13);
|
||||
function(A,B,C,D, 1, 3);
|
||||
function(D,A,B,C, 5, 5);
|
||||
function(C,D,A,B, 9, 9);
|
||||
function(B,C,D,A,13,13);
|
||||
function(A,B,C,D, 2, 3);
|
||||
function(D,A,B,C, 6, 5);
|
||||
function(C,D,A,B,10, 9);
|
||||
function(B,C,D,A,14,13);
|
||||
function(A,B,C,D, 3, 3);
|
||||
function(D,A,B,C, 7, 5);
|
||||
function(C,D,A,B,11, 9);
|
||||
function(B,C,D,A,15,13);
|
||||
|
||||
#undef function
|
||||
#define function(a,b,c,d,k,s) a=ROL(a+H(b,c,d)+X[k]+(U32)0x6ed9eba1,s);
|
||||
function(A,B,C,D, 0, 3);
|
||||
function(D,A,B,C, 8, 9);
|
||||
function(C,D,A,B, 4,11);
|
||||
function(B,C,D,A,12,15);
|
||||
function(A,B,C,D, 2, 3);
|
||||
function(D,A,B,C,10, 9);
|
||||
function(C,D,A,B, 6,11);
|
||||
function(B,C,D,A,14,15);
|
||||
function(A,B,C,D, 1, 3);
|
||||
function(D,A,B,C, 9, 9);
|
||||
function(C,D,A,B, 5,11);
|
||||
function(B,C,D,A,13,15);
|
||||
function(A,B,C,D, 3, 3);
|
||||
function(D,A,B,C,11, 9);
|
||||
function(C,D,A,B, 7,11);
|
||||
function(B,C,D,A,15,15);
|
||||
|
||||
self->A+=A; self->B+=B; self->C+=C; self->D+=D;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
hash_digest (const hash_state *self)
|
||||
{
|
||||
U8 digest[16];
|
||||
static U8 s[8];
|
||||
U32 padlen, oldlen1, oldlen2;
|
||||
hash_state temp;
|
||||
static U8 padding[64] = {
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
memcpy(&temp, self, sizeof(hash_state));
|
||||
oldlen1=temp.len1; oldlen2=temp.len2; /* Save current length */
|
||||
padlen= (56<=self->count) ? 56-self->count+64: 56-self->count;
|
||||
hash_update(&temp, padding, padlen);
|
||||
s[0]= oldlen1 & 255;
|
||||
s[1]=(oldlen1 >> 8) & 255;
|
||||
s[2]=(oldlen1 >> 16) & 255;
|
||||
s[3]=(oldlen1 >> 24) & 255;
|
||||
s[4]= oldlen2 & 255;
|
||||
s[5]=(oldlen2 >> 8) & 255;
|
||||
s[6]=(oldlen2 >> 16) & 255;
|
||||
s[7]=(oldlen2 >> 24) & 255;
|
||||
hash_update(&temp, s, 8);
|
||||
|
||||
digest[ 0]= temp.A & 255;
|
||||
digest[ 1]=(temp.A >> 8) & 255;
|
||||
digest[ 2]=(temp.A >> 16) & 255;
|
||||
digest[ 3]=(temp.A >> 24) & 255;
|
||||
digest[ 4]= temp.B & 255;
|
||||
digest[ 5]=(temp.B >> 8) & 255;
|
||||
digest[ 6]=(temp.B >> 16) & 255;
|
||||
digest[ 7]=(temp.B >> 24) & 255;
|
||||
digest[ 8]= temp.C & 255;
|
||||
digest[ 9]=(temp.C >> 8) & 255;
|
||||
digest[10]=(temp.C >> 16) & 255;
|
||||
digest[11]=(temp.C >> 24) & 255;
|
||||
digest[12]= temp.D & 255;
|
||||
digest[13]=(temp.D >> 8) & 255;
|
||||
digest[14]=(temp.D >> 16) & 255;
|
||||
digest[15]=(temp.D >> 24) & 255;
|
||||
|
||||
return PyString_FromStringAndSize(digest, 16);
|
||||
}
|
||||
|
||||
#include "hash_template.c"
|
@ -1,52 +0,0 @@
|
||||
/*
|
||||
* xor.c : Source for the trivial cipher which XORs the message with the key.
|
||||
* The key can be up to 32 bytes long.
|
||||
*
|
||||
* Part of the Python Cryptography Toolkit
|
||||
*
|
||||
* Distribute and use freely; there are no restrictions on further
|
||||
* dissemination and usage except those imposed by the laws of your
|
||||
* country of residence.
|
||||
*
|
||||
*/
|
||||
|
||||
#define MODULE_NAME XOR
|
||||
#define BLOCK_SIZE 1
|
||||
#define KEY_SIZE 0
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char key[32];
|
||||
int keylen, last_pos;
|
||||
} stream_state;
|
||||
|
||||
static void
|
||||
stream_init(stream_state *self, unsigned char *key, int len)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (32 <= len) len=32;
|
||||
self->keylen = len;
|
||||
self->last_pos = 0;
|
||||
|
||||
for(i=0; i<len; i++)
|
||||
{
|
||||
self->key[i] = key[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* Encryption and decryption are symmetric */
|
||||
#define stream_decrypt stream_encrypt
|
||||
|
||||
static void stream_encrypt(stream_state *self, unsigned char *block,
|
||||
int len)
|
||||
{
|
||||
int i, j = self->last_pos;
|
||||
for(i=0; i<len; i++, j=(j+1) % self->keylen)
|
||||
{
|
||||
block[i] ^= self->key[j];
|
||||
}
|
||||
self->last_pos = j;
|
||||
}
|
||||
|
||||
#include "stream_template.c"
|
@ -1,331 +0,0 @@
|
||||
|
||||
/*
|
||||
* _dsa.c: C implementation of the DSA algorithm.
|
||||
*
|
||||
* Part of the Python Cryptography Toolkit
|
||||
*
|
||||
* Distribute and use freely; there are no restrictions on further
|
||||
* dissemination and usage except those imposed by the laws of your
|
||||
* country of residence.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <Python.h>
|
||||
#include <longintrepr.h> /* for conversions */
|
||||
#include <gmp.h>
|
||||
|
||||
PyObject *_dsa_module;
|
||||
PyObject *_dsa_dict;
|
||||
|
||||
void
|
||||
longObjToMPZ (mpz_t m, PyLongObject * p)
|
||||
{
|
||||
int size, i;
|
||||
mpz_t temp, temp2;
|
||||
mpz_init (temp);
|
||||
mpz_init (temp2);
|
||||
if (p->ob_size > 0)
|
||||
size = p->ob_size;
|
||||
else
|
||||
size = -p->ob_size;
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
mpz_set_ui (temp, p->ob_digit[i]);
|
||||
mpz_mul_2exp (temp2, temp, SHIFT * i);
|
||||
mpz_add (m, m, temp2);
|
||||
}
|
||||
mpz_clear (temp);
|
||||
mpz_clear (temp2);
|
||||
}
|
||||
|
||||
PyObject *
|
||||
mpzToLongObj (mpz_t m)
|
||||
{
|
||||
/* borrowed from gmpy */
|
||||
int size = (mpz_sizeinbase (m, 2) + SHIFT - 1) / SHIFT;
|
||||
int i;
|
||||
mpz_t temp;
|
||||
PyLongObject *l = _PyLong_New (size);
|
||||
if (!l)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
mpz_init_set (temp, m);
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
l->ob_digit[i] = (digit) (mpz_get_ui (temp) & MASK);
|
||||
mpz_fdiv_q_2exp (temp, temp, SHIFT);
|
||||
}
|
||||
i = size;
|
||||
while ((i > 0) && (l->ob_digit[i - 1] == 0))
|
||||
i--;
|
||||
l->ob_size = i;
|
||||
mpz_clear (temp);
|
||||
return (PyObject *) l;
|
||||
}
|
||||
|
||||
PyObject *dsaKey_new (PyObject *, PyObject *);
|
||||
|
||||
static PyMethodDef _dsa__methods__[] = {
|
||||
{"construct", dsaKey_new, METH_VARARGS},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PyObject_HEAD mpz_t y;
|
||||
mpz_t g;
|
||||
mpz_t p;
|
||||
mpz_t q;
|
||||
mpz_t x;
|
||||
}
|
||||
dsaKey;
|
||||
|
||||
static int
|
||||
dsaSign (dsaKey * key, mpz_t m, mpz_t k, mpz_t r, mpz_t s)
|
||||
{
|
||||
mpz_t temp;
|
||||
if (mpz_cmp_ui (k, 2) < 0 || mpz_cmp (k, key->q) >= 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
mpz_init (temp);
|
||||
mpz_powm (r, key->g, k, key->p);
|
||||
mpz_mod (r, r, key->q);
|
||||
mpz_invert (s, k, key->q);
|
||||
mpz_mul (temp, key->x, r);
|
||||
mpz_add (temp, m, temp);
|
||||
mpz_mul (s, s, temp);
|
||||
mpz_mod (s, s, key->q);
|
||||
mpz_clear (temp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
dsaVerify (dsaKey * key, mpz_t m, mpz_t r, mpz_t s)
|
||||
{
|
||||
int result;
|
||||
mpz_t u1, u2, v1, v2, w;
|
||||
if (mpz_cmp_ui (r, 0) <= 0 || mpz_cmp (r, key->q) >= 0 ||
|
||||
mpz_cmp_ui (s, 0) <= 0 || mpz_cmp (s, key->q) >= 0)
|
||||
return 0;
|
||||
mpz_init (u1);
|
||||
mpz_init (u2);
|
||||
mpz_init (v1);
|
||||
mpz_init (v2);
|
||||
mpz_init (w);
|
||||
mpz_invert (w, s, key->q);
|
||||
mpz_mul (u1, m, w);
|
||||
mpz_mod (u1, u1, key->q);
|
||||
mpz_mul (u2, r, w);
|
||||
mpz_mod (u2, u2, key->q);
|
||||
mpz_powm (v1, key->g, u1, key->p);
|
||||
mpz_powm (v2, key->y, u2, key->p);
|
||||
mpz_mul (w, v1, v2);
|
||||
mpz_mod (w, w, key->p);
|
||||
mpz_mod (w, w, key->q);
|
||||
if (mpz_cmp (r, w) == 0)
|
||||
result = 1;
|
||||
else
|
||||
result = 0;
|
||||
mpz_clear (u1);
|
||||
mpz_clear (u2);
|
||||
mpz_clear (v1);
|
||||
mpz_clear (v2);
|
||||
mpz_clear (w);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void dsaKey_dealloc (dsaKey *);
|
||||
static PyObject *dsaKey_getattr (dsaKey *, char *);
|
||||
static PyObject *dsaKey__sign (dsaKey *, PyObject *);
|
||||
static PyObject *dsaKey__verify (dsaKey *, PyObject *);
|
||||
static PyObject *dsaKey_size (dsaKey *, PyObject *);
|
||||
static PyObject *dsaKey_hasprivate (dsaKey *, PyObject *);
|
||||
|
||||
PyObject *dsaError; /* raised on errors */
|
||||
|
||||
static PyTypeObject dsaKeyType = {
|
||||
PyObject_HEAD_INIT (NULL) 0,
|
||||
"dsaKey",
|
||||
sizeof (dsaKey),
|
||||
0,
|
||||
(destructor) dsaKey_dealloc, /* dealloc */
|
||||
0, /* print */
|
||||
(getattrfunc) dsaKey_getattr, /* getattr */
|
||||
0, /* setattr */
|
||||
0, /* compare */
|
||||
0, /* repr */
|
||||
0, /* as_number */
|
||||
0, /* as_sequence */
|
||||
0, /* as_mapping */
|
||||
0, /* hash */
|
||||
0, /* call */
|
||||
};
|
||||
|
||||
static PyMethodDef dsaKey__methods__[] = {
|
||||
{"_sign", (PyCFunction) dsaKey__sign, METH_VARARGS, "Sign the given long."},
|
||||
{"_verify", (PyCFunction) dsaKey__verify, METH_VARARGS,
|
||||
"Verify that the signature is valid."},
|
||||
{"size", (PyCFunction) dsaKey_size, METH_VARARGS,
|
||||
"Return the number of bits that this key can handle."},
|
||||
{"hasprivate", (PyCFunction) dsaKey_hasprivate, METH_VARARGS,
|
||||
"Return 1 or 0 if this key does/doesn't have a private key."},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
PyObject *
|
||||
dsaKey_new (PyObject * self, PyObject * args)
|
||||
{
|
||||
PyLongObject *y = NULL, *g = NULL, *p = NULL, *q = NULL, *x = NULL;
|
||||
dsaKey *key;
|
||||
key = PyObject_New (dsaKey, &dsaKeyType);
|
||||
mpz_init (key->y);
|
||||
mpz_init (key->g);
|
||||
mpz_init (key->p);
|
||||
mpz_init (key->q);
|
||||
mpz_init (key->x);
|
||||
PyArg_ParseTuple (args, "O!O!O!O!|O!", &PyLong_Type, &y,
|
||||
&PyLong_Type, &g,
|
||||
&PyLong_Type, &p, &PyLong_Type, &q, &PyLong_Type, &x);
|
||||
longObjToMPZ (key->y, y);
|
||||
longObjToMPZ (key->g, g);
|
||||
longObjToMPZ (key->p, p);
|
||||
longObjToMPZ (key->q, q);
|
||||
if (x)
|
||||
{
|
||||
longObjToMPZ (key->x, x);
|
||||
}
|
||||
/*Py_XDECREF(n);
|
||||
Py_XDECREF(e);
|
||||
Py_XDECREF(d);
|
||||
Py_XDECREF(p);
|
||||
Py_XDECREF(q); */
|
||||
return (PyObject *) key;
|
||||
}
|
||||
|
||||
static void
|
||||
dsaKey_dealloc (dsaKey * key)
|
||||
{
|
||||
mpz_clear (key->y);
|
||||
mpz_clear (key->g);
|
||||
mpz_clear (key->p);
|
||||
mpz_clear (key->q);
|
||||
mpz_clear (key->x);
|
||||
PyObject_Del (key);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
dsaKey_getattr (dsaKey * key, char *attr)
|
||||
{
|
||||
if (strcmp (attr, "y") == 0)
|
||||
return mpzToLongObj (key->y);
|
||||
else if (strcmp (attr, "g") == 0)
|
||||
return mpzToLongObj (key->g);
|
||||
else if (strcmp (attr, "p") == 0)
|
||||
return mpzToLongObj (key->p);
|
||||
else if (strcmp (attr, "q") == 0)
|
||||
return mpzToLongObj (key->q);
|
||||
else if (strcmp (attr, "x") == 0)
|
||||
{
|
||||
if (mpz_size (key->x) == 0)
|
||||
{
|
||||
PyErr_SetString (PyExc_AttributeError,
|
||||
"rsaKey instance has no attribute 'x'");
|
||||
return NULL;
|
||||
}
|
||||
return mpzToLongObj (key->x);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Py_FindMethod (dsaKey__methods__, (PyObject *) key, attr);
|
||||
}
|
||||
}
|
||||
|
||||
PyObject *
|
||||
dsaKey__sign (dsaKey * key, PyObject * args)
|
||||
{
|
||||
PyObject *lm, *lk, *lr, *ls;
|
||||
mpz_t m, k, r, s;
|
||||
int result;
|
||||
if (!(PyArg_ParseTuple (args, "O!O!", &PyLong_Type, &lm,
|
||||
&PyLong_Type, &lk)))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
mpz_init (m);
|
||||
mpz_init (k);
|
||||
mpz_init (r);
|
||||
mpz_init (s);
|
||||
longObjToMPZ (m, (PyLongObject *) lm);
|
||||
longObjToMPZ (k, (PyLongObject *) lk);
|
||||
result = dsaSign (key, m, k, r, s);
|
||||
if (result == 1)
|
||||
{
|
||||
PyErr_SetString (dsaError, "K not between 2 and q");
|
||||
return NULL;
|
||||
}
|
||||
lr = mpzToLongObj (r);
|
||||
ls = mpzToLongObj (s);
|
||||
mpz_clear (m);
|
||||
mpz_clear (k);
|
||||
mpz_clear (r);
|
||||
mpz_clear (s);
|
||||
return Py_BuildValue ("(NN)", lr, ls);
|
||||
}
|
||||
|
||||
PyObject *
|
||||
dsaKey__verify (dsaKey * key, PyObject * args)
|
||||
{
|
||||
PyObject *lm, *lr, *ls;
|
||||
mpz_t m, r, s;
|
||||
int result;
|
||||
if (!(PyArg_ParseTuple (args, "O!O!O!", &PyLong_Type, &lm,
|
||||
&PyLong_Type, &lr, &PyLong_Type, &ls)))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
mpz_init (m);
|
||||
mpz_init (r);
|
||||
mpz_init (s);
|
||||
longObjToMPZ (m, (PyLongObject *) lm);
|
||||
longObjToMPZ (r, (PyLongObject *) lr);
|
||||
longObjToMPZ (s, (PyLongObject *) ls);
|
||||
result = dsaVerify (key, m, r, s);
|
||||
mpz_clear (m);
|
||||
mpz_clear (r);
|
||||
mpz_clear (s);
|
||||
return Py_BuildValue ("i", result);
|
||||
}
|
||||
|
||||
PyObject *
|
||||
dsaKey_size (dsaKey * key, PyObject * args)
|
||||
{
|
||||
if (!PyArg_ParseTuple (args, ""))
|
||||
return NULL;
|
||||
return Py_BuildValue ("i", mpz_sizeinbase (key->p, 2) - 1);
|
||||
}
|
||||
|
||||
PyObject *
|
||||
dsaKey_hasprivate (dsaKey * key, PyObject * args)
|
||||
{
|
||||
if (!PyArg_ParseTuple (args, ""))
|
||||
return NULL;
|
||||
if (mpz_size (key->x) == 0)
|
||||
return Py_BuildValue ("i", 0);
|
||||
else
|
||||
return Py_BuildValue ("i", 1);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
init_dsa (void)
|
||||
{
|
||||
dsaKeyType.ob_type = &PyType_Type;
|
||||
_dsa_module = Py_InitModule ("_dsa", _dsa__methods__);
|
||||
_dsa_dict = PyModule_GetDict (_dsa_module);
|
||||
dsaError = PyErr_NewException ("_dsa.error", NULL, NULL);
|
||||
PyDict_SetItemString (_dsa_dict, "error", dsaError);
|
||||
}
|
@ -1,804 +0,0 @@
|
||||
|
||||
/*
|
||||
* _fastmath.c: Accelerator module that uses GMP for faster numerics.
|
||||
*
|
||||
* Part of the Python Cryptography Toolkit
|
||||
*
|
||||
* Distribute and use freely; there are no restrictions on further
|
||||
* dissemination and usage except those imposed by the laws of your
|
||||
* country of residence.
|
||||
*
|
||||
* $Id: _fastmath.c,v 1.13 2003/04/04 19:20:29 jbontje Exp $
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <Python.h>
|
||||
#include <longintrepr.h> /* for conversions */
|
||||
#include <gmp.h>
|
||||
|
||||
void
|
||||
longObjToMPZ (mpz_t m, PyLongObject * p)
|
||||
{
|
||||
int size, i;
|
||||
mpz_t temp, temp2;
|
||||
mpz_init (temp);
|
||||
mpz_init (temp2);
|
||||
if (p->ob_size > 0)
|
||||
size = p->ob_size;
|
||||
else
|
||||
size = -p->ob_size;
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
mpz_set_ui (temp, p->ob_digit[i]);
|
||||
mpz_mul_2exp (temp2, temp, SHIFT * i);
|
||||
mpz_add (m, m, temp2);
|
||||
}
|
||||
mpz_clear (temp);
|
||||
mpz_clear (temp2);
|
||||
}
|
||||
|
||||
PyObject *
|
||||
mpzToLongObj (mpz_t m)
|
||||
{
|
||||
/* borrowed from gmpy */
|
||||
int size = (mpz_sizeinbase (m, 2) + SHIFT - 1) / SHIFT;
|
||||
int i;
|
||||
mpz_t temp;
|
||||
PyLongObject *l = _PyLong_New (size);
|
||||
if (!l)
|
||||
return NULL;
|
||||
mpz_init_set (temp, m);
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
l->ob_digit[i] = (digit) (mpz_get_ui (temp) & MASK);
|
||||
mpz_fdiv_q_2exp (temp, temp, SHIFT);
|
||||
}
|
||||
i = size;
|
||||
while ((i > 0) && (l->ob_digit[i - 1] == 0))
|
||||
i--;
|
||||
l->ob_size = i;
|
||||
mpz_clear (temp);
|
||||
return (PyObject *) l;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PyObject_HEAD mpz_t y;
|
||||
mpz_t g;
|
||||
mpz_t p;
|
||||
mpz_t q;
|
||||
mpz_t x;
|
||||
}
|
||||
dsaKey;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PyObject_HEAD mpz_t n;
|
||||
mpz_t e;
|
||||
mpz_t d;
|
||||
mpz_t p;
|
||||
mpz_t q;
|
||||
mpz_t u;
|
||||
}
|
||||
rsaKey;
|
||||
|
||||
PyObject *rsaKey_new (PyObject *, PyObject *);
|
||||
PyObject *dsaKey_new (PyObject *, PyObject *);
|
||||
|
||||
static void dsaKey_dealloc (dsaKey *);
|
||||
static PyObject *dsaKey_getattr (dsaKey *, char *);
|
||||
static PyObject *dsaKey__sign (dsaKey *, PyObject *);
|
||||
static PyObject *dsaKey__verify (dsaKey *, PyObject *);
|
||||
static PyObject *dsaKey_size (dsaKey *, PyObject *);
|
||||
static PyObject *dsaKey_has_private (dsaKey *, PyObject *);
|
||||
|
||||
static void rsaKey_dealloc (rsaKey *);
|
||||
static PyObject *rsaKey_getattr (rsaKey *, char *);
|
||||
static PyObject *rsaKey__encrypt (rsaKey *, PyObject *);
|
||||
static PyObject *rsaKey__decrypt (rsaKey *, PyObject *);
|
||||
static PyObject *rsaKey__verify (rsaKey *, PyObject *);
|
||||
static PyObject *rsaKey__blind (rsaKey *, PyObject *);
|
||||
static PyObject *rsaKey__unblind (rsaKey *, PyObject *);
|
||||
static PyObject *rsaKey_size (rsaKey *, PyObject *);
|
||||
static PyObject *rsaKey_has_private (rsaKey *, PyObject *);
|
||||
|
||||
static int
|
||||
dsaSign (dsaKey * key, mpz_t m, mpz_t k, mpz_t r, mpz_t s)
|
||||
{
|
||||
mpz_t temp;
|
||||
if (mpz_cmp_ui (k, 2) < 0 || mpz_cmp (k, key->q) >= 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
mpz_init (temp);
|
||||
mpz_powm (r, key->g, k, key->p);
|
||||
mpz_mod (r, r, key->q);
|
||||
mpz_invert (s, k, key->q);
|
||||
mpz_mul (temp, key->x, r);
|
||||
mpz_add (temp, m, temp);
|
||||
mpz_mul (s, s, temp);
|
||||
mpz_mod (s, s, key->q);
|
||||
mpz_clear (temp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
dsaVerify (dsaKey * key, mpz_t m, mpz_t r, mpz_t s)
|
||||
{
|
||||
int result;
|
||||
mpz_t u1, u2, v1, v2, w;
|
||||
if (mpz_cmp_ui (r, 0) <= 0 || mpz_cmp (r, key->q) >= 0 ||
|
||||
mpz_cmp_ui (s, 0) <= 0 || mpz_cmp (s, key->q) >= 0)
|
||||
return 0;
|
||||
mpz_init (u1);
|
||||
mpz_init (u2);
|
||||
mpz_init (v1);
|
||||
mpz_init (v2);
|
||||
mpz_init (w);
|
||||
mpz_invert (w, s, key->q);
|
||||
mpz_mul (u1, m, w);
|
||||
mpz_mod (u1, u1, key->q);
|
||||
mpz_mul (u2, r, w);
|
||||
mpz_mod (u2, u2, key->q);
|
||||
mpz_powm (v1, key->g, u1, key->p);
|
||||
mpz_powm (v2, key->y, u2, key->p);
|
||||
mpz_mul (w, v1, v2);
|
||||
mpz_mod (w, w, key->p);
|
||||
mpz_mod (w, w, key->q);
|
||||
if (mpz_cmp (r, w) == 0)
|
||||
result = 1;
|
||||
else
|
||||
result = 0;
|
||||
mpz_clear (u1);
|
||||
mpz_clear (u2);
|
||||
mpz_clear (v1);
|
||||
mpz_clear (v2);
|
||||
mpz_clear (w);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
rsaEncrypt (rsaKey * key, mpz_t v)
|
||||
{
|
||||
if (mpz_cmp (v, key->n) >= 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
mpz_powm (v, v, key->e, key->n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
rsaDecrypt (rsaKey * key, mpz_t v)
|
||||
{
|
||||
mpz_t m1, m2, h;
|
||||
if (mpz_cmp (v, key->n) >= 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (mpz_size (key->d) == 0)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
if ((mpz_size (key->p) != 0) && (mpz_size (key->q) != 0) &&
|
||||
(mpz_size (key->u) != 0))
|
||||
{
|
||||
/* fast path */
|
||||
mpz_init(m1);
|
||||
mpz_init(m2);
|
||||
mpz_init(h);
|
||||
|
||||
/* m1 = c ^ (d mod (p-1)) mod p */
|
||||
mpz_sub_ui(h, key->p, 1);
|
||||
mpz_fdiv_r(h, key->d, h);
|
||||
mpz_powm(m1, v, h, key->p);
|
||||
/* m2 = c ^ (d mod (q-1)) mod q */
|
||||
mpz_sub_ui(h, key->q, 1);
|
||||
mpz_fdiv_r(h, key->d, h);
|
||||
mpz_powm(m2, v, h, key->q);
|
||||
/* h = u * ( m2 - m1 ) mod q */
|
||||
mpz_sub(h, m2, m1);
|
||||
if (mpz_sgn(h)==-1)
|
||||
mpz_add(h, h, key->q);
|
||||
mpz_mul(h, key->u, h);
|
||||
mpz_mod(h, h, key->q);
|
||||
/* m = m2 + h * p */
|
||||
mpz_mul(h, h, key->p);
|
||||
mpz_add(v, m1, h);
|
||||
/* ready */
|
||||
|
||||
mpz_clear(m1);
|
||||
mpz_clear(m2);
|
||||
mpz_clear(h);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* slow */
|
||||
mpz_powm (v, v, key->d, key->n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
rsaBlind (rsaKey * key, mpz_t v, mpz_t b)
|
||||
{
|
||||
if (mpz_cmp (v, key->n) >= 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (mpz_cmp (b, key->n) >= 0)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
mpz_powm (b, b, key->e, key->n);
|
||||
mpz_mul (v, v, b);
|
||||
mpz_mod (v, v, key->n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
rsaUnBlind (rsaKey * key, mpz_t v, mpz_t b)
|
||||
{
|
||||
if (mpz_cmp (v, key->n) >= 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (mpz_cmp (b, key->n) >= 0)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
if (!mpz_invert (b, b, key->n))
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
mpz_mul (v, v, b);
|
||||
mpz_mod (v, v, key->n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static PyTypeObject dsaKeyType = {
|
||||
PyObject_HEAD_INIT (NULL) 0,
|
||||
"dsaKey",
|
||||
sizeof (dsaKey),
|
||||
0,
|
||||
(destructor) dsaKey_dealloc, /* dealloc */
|
||||
0, /* print */
|
||||
(getattrfunc) dsaKey_getattr, /* getattr */
|
||||
0, /* setattr */
|
||||
0, /* compare */
|
||||
0, /* repr */
|
||||
0, /* as_number */
|
||||
0, /* as_sequence */
|
||||
0, /* as_mapping */
|
||||
0, /* hash */
|
||||
0, /* call */
|
||||
};
|
||||
|
||||
static PyMethodDef dsaKey__methods__[] = {
|
||||
{"_sign", (PyCFunction) dsaKey__sign, METH_VARARGS,
|
||||
"Sign the given long."},
|
||||
{"_verify", (PyCFunction) dsaKey__verify, METH_VARARGS,
|
||||
"Verify that the signature is valid."},
|
||||
{"size", (PyCFunction) dsaKey_size, METH_VARARGS,
|
||||
"Return the number of bits that this key can handle."},
|
||||
{"has_private", (PyCFunction) dsaKey_has_private, METH_VARARGS,
|
||||
"Return 1 or 0 if this key does/doesn't have a private key."},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
PyObject *fastmathError; /* raised on errors */
|
||||
|
||||
static PyTypeObject rsaKeyType = {
|
||||
PyObject_HEAD_INIT (NULL) 0,
|
||||
"rsaKey",
|
||||
sizeof (rsaKey),
|
||||
0,
|
||||
(destructor) rsaKey_dealloc, /* dealloc */
|
||||
0, /* print */
|
||||
(getattrfunc) rsaKey_getattr, /* getattr */
|
||||
0, /* setattr */
|
||||
0, /* compare */
|
||||
0, /* repr */
|
||||
0, /* as_number */
|
||||
0, /* as_sequence */
|
||||
0, /* as_mapping */
|
||||
0, /* hash */
|
||||
0, /* call */
|
||||
};
|
||||
|
||||
static PyMethodDef rsaKey__methods__[] = {
|
||||
{"_encrypt", (PyCFunction) rsaKey__encrypt, METH_VARARGS,
|
||||
"Encrypt the given long."},
|
||||
{"_decrypt", (PyCFunction) rsaKey__decrypt, METH_VARARGS,
|
||||
"Decrypt the given long."},
|
||||
{"_sign", (PyCFunction) rsaKey__decrypt, METH_VARARGS,
|
||||
"Sign the given long."},
|
||||
{"_verify", (PyCFunction) rsaKey__verify, METH_VARARGS,
|
||||
"Verify that the signature is valid."},
|
||||
{"_blind", (PyCFunction) rsaKey__blind, METH_VARARGS,
|
||||
"Blind the given long."},
|
||||
{"_unblind", (PyCFunction) rsaKey__unblind, METH_VARARGS,
|
||||
"Unblind the given long."},
|
||||
{"size", (PyCFunction) rsaKey_size, METH_VARARGS,
|
||||
"Return the number of bits that this key can handle."},
|
||||
{"has_private", (PyCFunction) rsaKey_has_private, METH_VARARGS,
|
||||
"Return 1 or 0 if this key does/doesn't have a private key."},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
PyObject *
|
||||
dsaKey_new (PyObject * self, PyObject * args)
|
||||
{
|
||||
PyLongObject *y = NULL, *g = NULL, *p = NULL, *q = NULL, *x = NULL;
|
||||
dsaKey *key;
|
||||
if (!PyArg_ParseTuple(args, "O!O!O!O!|O!", &PyLong_Type, &y,
|
||||
&PyLong_Type, &g, &PyLong_Type, &p,
|
||||
&PyLong_Type, &q, &PyLong_Type, &x))
|
||||
return NULL;
|
||||
|
||||
key = PyObject_New (dsaKey, &dsaKeyType);
|
||||
mpz_init (key->y);
|
||||
mpz_init (key->g);
|
||||
mpz_init (key->p);
|
||||
mpz_init (key->q);
|
||||
mpz_init (key->x);
|
||||
longObjToMPZ (key->y, y);
|
||||
longObjToMPZ (key->g, g);
|
||||
longObjToMPZ (key->p, p);
|
||||
longObjToMPZ (key->q, q);
|
||||
if (x)
|
||||
{
|
||||
longObjToMPZ (key->x, x);
|
||||
}
|
||||
return (PyObject *) key;
|
||||
}
|
||||
|
||||
static void
|
||||
dsaKey_dealloc (dsaKey * key)
|
||||
{
|
||||
mpz_clear (key->y);
|
||||
mpz_clear (key->g);
|
||||
mpz_clear (key->p);
|
||||
mpz_clear (key->q);
|
||||
mpz_clear (key->x);
|
||||
PyObject_Del (key);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
dsaKey_getattr (dsaKey * key, char *attr)
|
||||
{
|
||||
if (strcmp (attr, "y") == 0)
|
||||
return mpzToLongObj (key->y);
|
||||
else if (strcmp (attr, "g") == 0)
|
||||
return mpzToLongObj (key->g);
|
||||
else if (strcmp (attr, "p") == 0)
|
||||
return mpzToLongObj (key->p);
|
||||
else if (strcmp (attr, "q") == 0)
|
||||
return mpzToLongObj (key->q);
|
||||
else if (strcmp (attr, "x") == 0)
|
||||
{
|
||||
if (mpz_size (key->x) == 0)
|
||||
{
|
||||
PyErr_SetString (PyExc_AttributeError,
|
||||
"dsaKey instance has no attribute 'x'");
|
||||
return NULL;
|
||||
}
|
||||
return mpzToLongObj (key->x);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Py_FindMethod (dsaKey__methods__, (PyObject *) key, attr);
|
||||
}
|
||||
}
|
||||
|
||||
PyObject *
|
||||
dsaKey__sign (dsaKey * key, PyObject * args)
|
||||
{
|
||||
PyObject *lm, *lk, *lr, *ls;
|
||||
mpz_t m, k, r, s;
|
||||
int result;
|
||||
if (!PyArg_ParseTuple (args, "O!O!", &PyLong_Type, &lm,
|
||||
&PyLong_Type, &lk))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
mpz_init (m);
|
||||
mpz_init (k);
|
||||
mpz_init (r);
|
||||
mpz_init (s);
|
||||
longObjToMPZ (m, (PyLongObject *) lm);
|
||||
longObjToMPZ (k, (PyLongObject *) lk);
|
||||
result = dsaSign (key, m, k, r, s);
|
||||
if (result == 1)
|
||||
{
|
||||
PyErr_SetString (fastmathError, "K not between 2 and q");
|
||||
return NULL;
|
||||
}
|
||||
lr = mpzToLongObj (r);
|
||||
ls = mpzToLongObj (s);
|
||||
mpz_clear (m);
|
||||
mpz_clear (k);
|
||||
mpz_clear (r);
|
||||
mpz_clear (s);
|
||||
return Py_BuildValue ("(NN)", lr, ls);
|
||||
}
|
||||
|
||||
PyObject *
|
||||
dsaKey__verify (dsaKey * key, PyObject * args)
|
||||
{
|
||||
PyObject *lm, *lr, *ls;
|
||||
mpz_t m, r, s;
|
||||
int result;
|
||||
if (!PyArg_ParseTuple (args, "O!O!O!", &PyLong_Type, &lm,
|
||||
&PyLong_Type, &lr, &PyLong_Type, &ls))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
mpz_init (m);
|
||||
mpz_init (r);
|
||||
mpz_init (s);
|
||||
longObjToMPZ (m, (PyLongObject *) lm);
|
||||
longObjToMPZ (r, (PyLongObject *) lr);
|
||||
longObjToMPZ (s, (PyLongObject *) ls);
|
||||
result = dsaVerify (key, m, r, s);
|
||||
mpz_clear (m);
|
||||
mpz_clear (r);
|
||||
mpz_clear (s);
|
||||
if (result) {
|
||||
Py_INCREF(Py_True);
|
||||
return Py_True;
|
||||
} else {
|
||||
Py_INCREF(Py_False);
|
||||
return Py_False;
|
||||
}
|
||||
}
|
||||
|
||||
PyObject *
|
||||
dsaKey_size (dsaKey * key, PyObject * args)
|
||||
{
|
||||
if (!PyArg_ParseTuple (args, ""))
|
||||
return NULL;
|
||||
return Py_BuildValue ("i", mpz_sizeinbase (key->p, 2) - 1);
|
||||
}
|
||||
|
||||
PyObject *
|
||||
dsaKey_has_private (dsaKey * key, PyObject * args)
|
||||
{
|
||||
if (!PyArg_ParseTuple (args, ""))
|
||||
return NULL;
|
||||
if (mpz_size (key->x) == 0) {
|
||||
Py_INCREF(Py_False);
|
||||
return Py_False;
|
||||
} else {
|
||||
Py_INCREF(Py_True);
|
||||
return Py_True;
|
||||
}
|
||||
}
|
||||
|
||||
PyObject *
|
||||
rsaKey_new (PyObject * self, PyObject * args)
|
||||
{
|
||||
PyLongObject *n = NULL, *e = NULL, *d = NULL, *p = NULL, *q = NULL,
|
||||
*u = NULL;
|
||||
rsaKey *key;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "O!O!|O!O!O!O!", &PyLong_Type, &n,
|
||||
&PyLong_Type, &e, &PyLong_Type, &d,
|
||||
&PyLong_Type, &p, &PyLong_Type, &q,
|
||||
&PyLong_Type, &u))
|
||||
return NULL;
|
||||
|
||||
key = PyObject_New (rsaKey, &rsaKeyType);
|
||||
mpz_init (key->n);
|
||||
mpz_init (key->e);
|
||||
mpz_init (key->d);
|
||||
mpz_init (key->p);
|
||||
mpz_init (key->q);
|
||||
mpz_init (key->u);
|
||||
longObjToMPZ (key->n, n);
|
||||
longObjToMPZ (key->e, e);
|
||||
if (!d)
|
||||
{
|
||||
return (PyObject *) key;
|
||||
}
|
||||
longObjToMPZ (key->d, d);
|
||||
if (p && q)
|
||||
{
|
||||
longObjToMPZ (key->p, p);
|
||||
longObjToMPZ (key->q, q);
|
||||
if (u) {
|
||||
longObjToMPZ (key->u, u);
|
||||
} else {
|
||||
mpz_invert (key->u, key->p, key->q);
|
||||
}
|
||||
}
|
||||
return (PyObject *) key;
|
||||
}
|
||||
|
||||
static void
|
||||
rsaKey_dealloc (rsaKey * key)
|
||||
{
|
||||
mpz_clear (key->n);
|
||||
mpz_clear (key->e);
|
||||
mpz_clear (key->d);
|
||||
mpz_clear (key->p);
|
||||
mpz_clear (key->q);
|
||||
mpz_clear (key->u);
|
||||
PyObject_Del (key);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
rsaKey_getattr (rsaKey * key, char *attr)
|
||||
{
|
||||
if (strcmp (attr, "n") == 0)
|
||||
return mpzToLongObj (key->n);
|
||||
else if (strcmp (attr, "e") == 0)
|
||||
return mpzToLongObj (key->e);
|
||||
else if (strcmp (attr, "d") == 0)
|
||||
{
|
||||
if (mpz_size (key->d) == 0)
|
||||
{
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
"rsaKey instance has no attribute 'd'");
|
||||
return NULL;
|
||||
}
|
||||
return mpzToLongObj (key->d);
|
||||
}
|
||||
else if (strcmp (attr, "p") == 0)
|
||||
{
|
||||
if (mpz_size (key->p) == 0)
|
||||
{
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
"rsaKey instance has no attribute 'p'");
|
||||
return NULL;
|
||||
}
|
||||
return mpzToLongObj (key->p);
|
||||
}
|
||||
else if (strcmp (attr, "q") == 0)
|
||||
{
|
||||
if (mpz_size (key->q) == 0)
|
||||
{
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
"rsaKey instance has no attribute 'q'");
|
||||
return NULL;
|
||||
}
|
||||
return mpzToLongObj (key->q);
|
||||
}
|
||||
else if (strcmp (attr, "u") == 0)
|
||||
{
|
||||
if (mpz_size (key->u) == 0)
|
||||
{
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
"rsaKey instance has no attribute 'u'");
|
||||
return NULL;
|
||||
}
|
||||
return mpzToLongObj (key->u);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Py_FindMethod (rsaKey__methods__,
|
||||
(PyObject *) key, attr);
|
||||
}
|
||||
}
|
||||
|
||||
PyObject *
|
||||
rsaKey__encrypt (rsaKey * key, PyObject * args)
|
||||
{
|
||||
PyObject *l, *r;
|
||||
mpz_t v;
|
||||
int result;
|
||||
if (!PyArg_ParseTuple (args, "O!", &PyLong_Type, &l))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
mpz_init (v);
|
||||
longObjToMPZ (v, (PyLongObject *) l);
|
||||
result = rsaEncrypt (key, v);
|
||||
if (result == 1)
|
||||
{
|
||||
PyErr_SetString (fastmathError, "Plaintext too large");
|
||||
return NULL;
|
||||
}
|
||||
r = (PyObject *) mpzToLongObj (v);
|
||||
mpz_clear (v);
|
||||
return Py_BuildValue ("N", r);
|
||||
}
|
||||
|
||||
PyObject *
|
||||
rsaKey__decrypt (rsaKey * key, PyObject * args)
|
||||
{
|
||||
PyObject *l, *r;
|
||||
mpz_t v;
|
||||
int result;
|
||||
if (!PyArg_ParseTuple (args, "O!", &PyLong_Type, &l))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
mpz_init (v);
|
||||
longObjToMPZ (v, (PyLongObject *) l);
|
||||
result = rsaDecrypt (key, v);
|
||||
if (result == 1)
|
||||
{
|
||||
PyErr_SetString (fastmathError,
|
||||
"Ciphertext too large");
|
||||
return NULL;
|
||||
}
|
||||
else if (result == 2)
|
||||
{
|
||||
PyErr_SetString (fastmathError,
|
||||
"Private key not available in this object");
|
||||
return NULL;
|
||||
}
|
||||
r = mpzToLongObj (v);
|
||||
mpz_clear (v);
|
||||
return Py_BuildValue ("N", r);
|
||||
}
|
||||
|
||||
PyObject *
|
||||
rsaKey__verify (rsaKey * key, PyObject * args)
|
||||
{
|
||||
PyObject *l, *lsig;
|
||||
mpz_t v, vsig;
|
||||
if (!PyArg_ParseTuple(args, "O!O!",
|
||||
&PyLong_Type, &l, &PyLong_Type, &lsig))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
mpz_init (v);
|
||||
mpz_init (vsig);
|
||||
longObjToMPZ (v, (PyLongObject *) l);
|
||||
longObjToMPZ (vsig, (PyLongObject *) lsig);
|
||||
rsaEncrypt (key, vsig);
|
||||
if (mpz_cmp (v, vsig) == 0) {
|
||||
Py_INCREF(Py_True);
|
||||
return Py_True;
|
||||
}
|
||||
else {
|
||||
Py_INCREF(Py_False);
|
||||
return Py_False;
|
||||
}
|
||||
}
|
||||
|
||||
PyObject *
|
||||
rsaKey__blind (rsaKey * key, PyObject * args)
|
||||
{
|
||||
PyObject *l, *lblind, *r;
|
||||
mpz_t v, vblind;
|
||||
int result;
|
||||
if (!PyArg_ParseTuple (args, "O!O!", &PyLong_Type, &l,
|
||||
&PyLong_Type, &lblind))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
mpz_init (v);
|
||||
mpz_init (vblind);
|
||||
longObjToMPZ (v, (PyLongObject *) l);
|
||||
longObjToMPZ (vblind, (PyLongObject *) lblind);
|
||||
result = rsaBlind (key, v, vblind);
|
||||
if (result == 1)
|
||||
{
|
||||
PyErr_SetString (fastmathError, "Message too large");
|
||||
return NULL;
|
||||
}
|
||||
else if (result == 2)
|
||||
{
|
||||
PyErr_SetString (fastmathError, "Blinding factor too large");
|
||||
return NULL;
|
||||
}
|
||||
r = (PyObject *) mpzToLongObj (v);
|
||||
mpz_clear (v);
|
||||
mpz_clear (vblind);
|
||||
return Py_BuildValue ("N", r);
|
||||
}
|
||||
|
||||
PyObject *
|
||||
rsaKey__unblind (rsaKey * key, PyObject * args)
|
||||
{
|
||||
PyObject *l, *lblind, *r;
|
||||
mpz_t v, vblind;
|
||||
int result;
|
||||
if (!PyArg_ParseTuple (args, "O!O!", &PyLong_Type, &l,
|
||||
&PyLong_Type, &lblind))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
mpz_init (v);
|
||||
mpz_init (vblind);
|
||||
longObjToMPZ (v, (PyLongObject *) l);
|
||||
longObjToMPZ (vblind, (PyLongObject *) lblind);
|
||||
result = rsaUnBlind (key, v, vblind);
|
||||
if (result == 1)
|
||||
{
|
||||
PyErr_SetString (fastmathError, "Message too large");
|
||||
return NULL;
|
||||
}
|
||||
else if (result == 2)
|
||||
{
|
||||
PyErr_SetString (fastmathError, "Blinding factor too large");
|
||||
return NULL;
|
||||
}
|
||||
else if (result == 3)
|
||||
{
|
||||
PyErr_SetString (fastmathError, "Inverse doesn't exist");
|
||||
return NULL;
|
||||
}
|
||||
r = (PyObject *) mpzToLongObj (v);
|
||||
mpz_clear (v);
|
||||
mpz_clear (vblind);
|
||||
return Py_BuildValue ("N", r);
|
||||
}
|
||||
|
||||
PyObject *
|
||||
rsaKey_size (rsaKey * key, PyObject * args)
|
||||
{
|
||||
if (!PyArg_ParseTuple (args, ""))
|
||||
return NULL;
|
||||
return Py_BuildValue ("i", mpz_sizeinbase (key->n, 2) - 1);
|
||||
}
|
||||
|
||||
PyObject *
|
||||
rsaKey_has_private (rsaKey * key, PyObject * args)
|
||||
{
|
||||
if (!PyArg_ParseTuple (args, ""))
|
||||
return NULL;
|
||||
if (mpz_size (key->d) == 0) {
|
||||
Py_INCREF(Py_False);
|
||||
return Py_False;
|
||||
} else {
|
||||
Py_INCREF(Py_True);
|
||||
return Py_True;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PyObject *
|
||||
isPrime (PyObject * self, PyObject * args)
|
||||
{
|
||||
PyObject *l;
|
||||
mpz_t n;
|
||||
int result;
|
||||
|
||||
if (!PyArg_ParseTuple (args, "O!", &PyLong_Type, &l))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
mpz_init (n);
|
||||
longObjToMPZ (n, (PyLongObject *) l);
|
||||
|
||||
result = mpz_probab_prime_p(n, 5);
|
||||
|
||||
mpz_clear (n);
|
||||
|
||||
if (result == 0) {
|
||||
Py_INCREF(Py_False);
|
||||
return Py_False;
|
||||
} else {
|
||||
Py_INCREF(Py_True);
|
||||
return Py_True;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static PyMethodDef _fastmath__methods__[] = {
|
||||
{"dsa_construct", dsaKey_new, METH_VARARGS},
|
||||
{"rsa_construct", rsaKey_new, METH_VARARGS},
|
||||
{"isPrime", isPrime, METH_VARARGS},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
void
|
||||
init_fastmath (void)
|
||||
{
|
||||
PyObject *_fastmath_module;
|
||||
PyObject *_fastmath_dict;
|
||||
|
||||
rsaKeyType.ob_type = &PyType_Type;
|
||||
dsaKeyType.ob_type = &PyType_Type;
|
||||
_fastmath_module = Py_InitModule ("_fastmath", _fastmath__methods__);
|
||||
_fastmath_dict = PyModule_GetDict (_fastmath_module);
|
||||
fastmathError = PyErr_NewException ("_fastmath.error", NULL, NULL);
|
||||
PyDict_SetItemString (_fastmath_dict, "error", fastmathError);
|
||||
}
|
@ -1,346 +0,0 @@
|
||||
|
||||
/*
|
||||
* _rsa.c: C implementation of the RSA algorithm.
|
||||
*
|
||||
* Part of the Python Cryptography Toolkit
|
||||
*
|
||||
* Distribute and use freely; there are no restrictions on further
|
||||
* dissemination and usage except those imposed by the laws of your
|
||||
* country of residence.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <Python.h>
|
||||
#include <longintrepr.h> /* for conversions */
|
||||
#include <gmp.h>
|
||||
|
||||
PyObject *_rsa_module;
|
||||
PyObject *_rsa_dict;
|
||||
|
||||
void
|
||||
longObjToMPZ (mpz_t m, PyLongObject * p)
|
||||
{
|
||||
int size, i;
|
||||
mpz_t temp, temp2;
|
||||
mpz_init (temp);
|
||||
mpz_init (temp2);
|
||||
if (p->ob_size > 0)
|
||||
size = p->ob_size;
|
||||
else
|
||||
size = -p->ob_size;
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
mpz_set_ui (temp, p->ob_digit[i]);
|
||||
mpz_mul_2exp (temp2, temp, SHIFT * i);
|
||||
mpz_add (m, m, temp2);
|
||||
}
|
||||
mpz_clear (temp);
|
||||
mpz_clear (temp2);
|
||||
}
|
||||
|
||||
PyObject *
|
||||
mpzToLongObj (mpz_t m)
|
||||
{
|
||||
/* borrowed from gmpy */
|
||||
int size = (mpz_sizeinbase (m, 2) + SHIFT - 1) / SHIFT;
|
||||
int i;
|
||||
mpz_t temp;
|
||||
PyLongObject *l = _PyLong_New (size);
|
||||
if (!l)
|
||||
return NULL;
|
||||
mpz_init_set (temp, m);
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
l->ob_digit[i] = (digit) (mpz_get_ui (temp) & MASK);
|
||||
mpz_fdiv_q_2exp (temp, temp, SHIFT);
|
||||
}
|
||||
i = size;
|
||||
while ((i > 0) && (l->ob_digit[i - 1] == 0))
|
||||
i--;
|
||||
l->ob_size = i;
|
||||
mpz_clear (temp);
|
||||
return (PyObject *) l;
|
||||
}
|
||||
|
||||
PyObject *rsaKey_new (PyObject *, PyObject *);
|
||||
|
||||
static PyMethodDef _rsa__methods__[] = {
|
||||
{"construct", rsaKey_new, METH_VARARGS},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PyObject_HEAD mpz_t n;
|
||||
mpz_t e;
|
||||
mpz_t d;
|
||||
mpz_t p;
|
||||
mpz_t q;
|
||||
}
|
||||
rsaKey;
|
||||
|
||||
static int
|
||||
rsaEncrypt (rsaKey * key, mpz_t v)
|
||||
{
|
||||
if (mpz_cmp (v, key->n) >= 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
mpz_powm (v, v, key->e, key->n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
rsaDecrypt (rsaKey * key, mpz_t v)
|
||||
{
|
||||
if (mpz_cmp (v, key->n) >= 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (mpz_size (key->d) == 0)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
mpz_powm (v, v, key->d, key->n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rsaKey_dealloc (rsaKey *);
|
||||
static PyObject *rsaKey_getattr (rsaKey *, char *);
|
||||
static PyObject *rsaKey__encrypt (rsaKey *, PyObject *);
|
||||
static PyObject *rsaKey__decrypt (rsaKey *, PyObject *);
|
||||
static PyObject *rsaKey__verify (rsaKey *, PyObject *);
|
||||
static PyObject *rsaKey_size (rsaKey *, PyObject *);
|
||||
static PyObject *rsaKey_hasprivate (rsaKey *, PyObject *);
|
||||
|
||||
PyObject *rsaError; /* raised on errors */
|
||||
|
||||
static PyTypeObject rsaKeyType = {
|
||||
PyObject_HEAD_INIT (NULL) 0,
|
||||
"rsaKey",
|
||||
sizeof (rsaKey),
|
||||
0,
|
||||
(destructor) rsaKey_dealloc, /* dealloc */
|
||||
0, /* print */
|
||||
(getattrfunc) rsaKey_getattr, /* getattr */
|
||||
0, /* setattr */
|
||||
0, /* compare */
|
||||
0, /* repr */
|
||||
0, /* as_number */
|
||||
0, /* as_sequence */
|
||||
0, /* as_mapping */
|
||||
0, /* hash */
|
||||
0, /* call */
|
||||
};
|
||||
|
||||
static PyMethodDef rsaKey__methods__[] = {
|
||||
{"_encrypt", (PyCFunction) rsaKey__encrypt, METH_VARARGS,
|
||||
"Encrypt the given long."},
|
||||
{"_decrypt", (PyCFunction) rsaKey__decrypt, METH_VARARGS,
|
||||
"Decrypt the given long."},
|
||||
{"_sign", (PyCFunction) rsaKey__decrypt, METH_VARARGS,
|
||||
"Sign the given long."},
|
||||
{"_verify", (PyCFunction) rsaKey__verify, METH_VARARGS,
|
||||
"Verify that the signature is valid."},
|
||||
{"size", (PyCFunction) rsaKey_size, METH_VARARGS,
|
||||
"Return the number of bits that this key can handle."},
|
||||
{"hasprivate", (PyCFunction) rsaKey_hasprivate, METH_VARARGS,
|
||||
"Return 1 or 0 if this key does/doesn't have a private key."},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
PyObject *
|
||||
rsaKey_new (PyObject * self, PyObject * args)
|
||||
{
|
||||
PyLongObject *n = NULL, *e = NULL, *d = NULL, *p = NULL, *q = NULL;
|
||||
rsaKey *key;
|
||||
key = PyObject_New (rsaKey, &rsaKeyType);
|
||||
mpz_init (key->n);
|
||||
mpz_init (key->e);
|
||||
mpz_init (key->d);
|
||||
mpz_init (key->p);
|
||||
mpz_init (key->q);
|
||||
PyArg_ParseTuple (args, "O!O!|O!O!O!", &PyLong_Type, &n,
|
||||
&PyLong_Type, &e,
|
||||
&PyLong_Type, &d, &PyLong_Type, &p, &PyLong_Type, &q);
|
||||
longObjToMPZ (key->n, n);
|
||||
longObjToMPZ (key->e, e);
|
||||
if (!d)
|
||||
{
|
||||
return (PyObject *) key;
|
||||
}
|
||||
longObjToMPZ (key->d, d);
|
||||
if (p)
|
||||
{
|
||||
if (q)
|
||||
{
|
||||
longObjToMPZ (key->p, p);
|
||||
longObjToMPZ (key->q, q);
|
||||
}
|
||||
}
|
||||
/*Py_XDECREF(n);
|
||||
Py_XDECREF(e);
|
||||
Py_XDECREF(d);
|
||||
Py_XDECREF(p);
|
||||
Py_XDECREF(q); */
|
||||
return (PyObject *) key;
|
||||
}
|
||||
|
||||
static void
|
||||
rsaKey_dealloc (rsaKey * key)
|
||||
{
|
||||
mpz_clear (key->n);
|
||||
mpz_clear (key->e);
|
||||
mpz_clear (key->d);
|
||||
mpz_clear (key->p);
|
||||
mpz_clear (key->q);
|
||||
PyObject_Del (key);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
rsaKey_getattr (rsaKey * key, char *attr)
|
||||
{
|
||||
if (strcmp (attr, "n") == 0)
|
||||
return mpzToLongObj (key->n);
|
||||
else if (strcmp (attr, "e") == 0)
|
||||
return mpzToLongObj (key->e);
|
||||
else if (strcmp (attr, "d") == 0)
|
||||
{
|
||||
if (mpz_size (key->d) == 0)
|
||||
{
|
||||
PyErr_SetString (PyExc_AttributeError,
|
||||
"rsaKey instance has no attribute 'd'");
|
||||
return NULL;
|
||||
}
|
||||
return mpzToLongObj (key->d);
|
||||
}
|
||||
else if (strcmp (attr, "p") == 0)
|
||||
{
|
||||
if (mpz_size (key->p) == 0)
|
||||
{
|
||||
PyErr_SetString (PyExc_AttributeError,
|
||||
"rsaKey instance has no attribute 'p'");
|
||||
return NULL;
|
||||
}
|
||||
return mpzToLongObj (key->p);
|
||||
}
|
||||
else if (strcmp (attr, "q") == 0)
|
||||
{
|
||||
if (mpz_size (key->q) == 0)
|
||||
{
|
||||
PyErr_SetString (PyExc_AttributeError,
|
||||
"rsaKey instance has no attribute 'q'");
|
||||
return NULL;
|
||||
}
|
||||
return mpzToLongObj (key->q);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Py_FindMethod (rsaKey__methods__, (PyObject *) key, attr);
|
||||
}
|
||||
}
|
||||
|
||||
PyObject *
|
||||
rsaKey__encrypt (rsaKey * key, PyObject * args)
|
||||
{
|
||||
PyObject *l, *r;
|
||||
mpz_t v;
|
||||
int result;
|
||||
if (!(PyArg_ParseTuple (args, "O!", &PyLong_Type, &l)))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
mpz_init (v);
|
||||
longObjToMPZ (v, (PyLongObject *) l);
|
||||
result = rsaEncrypt (key, v);
|
||||
if (result == 1)
|
||||
{
|
||||
PyErr_SetString (rsaError, "Plaintext too large");
|
||||
return NULL;
|
||||
}
|
||||
r = (PyObject *) mpzToLongObj (v);
|
||||
mpz_clear (v);
|
||||
return Py_BuildValue ("N", r);
|
||||
}
|
||||
|
||||
PyObject *
|
||||
rsaKey__decrypt (rsaKey * key, PyObject * args)
|
||||
{
|
||||
PyObject *l, *r;
|
||||
mpz_t v;
|
||||
int result;
|
||||
if (!(PyArg_ParseTuple (args, "O!", &PyLong_Type, &l)))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
mpz_init (v);
|
||||
longObjToMPZ (v, (PyLongObject *) l);
|
||||
result = rsaDecrypt (key, v);
|
||||
if (result == 1)
|
||||
{
|
||||
PyErr_SetString (rsaError, "Ciphertext too large");
|
||||
return NULL;
|
||||
}
|
||||
else if (result == 2)
|
||||
{
|
||||
PyErr_SetString (rsaError, "Private key not available in this object");
|
||||
return NULL;
|
||||
}
|
||||
r = mpzToLongObj (v);
|
||||
mpz_clear (v);
|
||||
return Py_BuildValue ("N", r);
|
||||
}
|
||||
|
||||
PyObject *
|
||||
rsaKey__verify (rsaKey * key, PyObject * args)
|
||||
{
|
||||
PyObject *l, *lsig;
|
||||
mpz_t v, vsig;
|
||||
if (!
|
||||
(PyArg_ParseTuple
|
||||
(args, "O!O!", &PyLong_Type, &l, &PyLong_Type, &lsig)))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
mpz_init (v);
|
||||
mpz_init (vsig);
|
||||
longObjToMPZ (v, (PyLongObject *) l);
|
||||
longObjToMPZ (vsig, (PyLongObject *) lsig);
|
||||
rsaEncrypt (key, vsig);
|
||||
if (mpz_cmp (v, vsig) == 0)
|
||||
return Py_BuildValue ("i", 1);
|
||||
else
|
||||
return Py_BuildValue ("i", 0);
|
||||
}
|
||||
|
||||
PyObject *
|
||||
rsaKey_size (rsaKey * key, PyObject * args)
|
||||
{
|
||||
if (!PyArg_ParseTuple (args, ""))
|
||||
return NULL;
|
||||
return Py_BuildValue ("i", mpz_sizeinbase (key->n, 2) - 1);
|
||||
}
|
||||
|
||||
PyObject *
|
||||
rsaKey_hasprivate (rsaKey * key, PyObject * args)
|
||||
{
|
||||
if (!PyArg_ParseTuple (args, ""))
|
||||
return NULL;
|
||||
if (mpz_size (key->d) == 0)
|
||||
return Py_BuildValue ("i", 0);
|
||||
else
|
||||
return Py_BuildValue ("i", 1);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
init_rsa (void)
|
||||
{
|
||||
rsaKeyType.ob_type = &PyType_Type;
|
||||
_rsa_module = Py_InitModule ("_rsa", _rsa__methods__);
|
||||
_rsa_dict = PyModule_GetDict (_rsa_module);
|
||||
rsaError = PyErr_NewException ("_rsa.error", NULL, NULL);
|
||||
PyDict_SetItemString (_rsa_dict, "error", rsaError);
|
||||
}
|
@ -1,437 +0,0 @@
|
||||
/*
|
||||
These are the S-boxes for CAST5 as given in RFC 2144.
|
||||
*/
|
||||
|
||||
|
||||
static const uint32 S1[256] = {
|
||||
0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f,
|
||||
0x9c004dd3, 0x6003e540, 0xcf9fc949, 0xbfd4af27, 0x88bbbdb5,
|
||||
0xe2034090, 0x98d09675, 0x6e63a0e0, 0x15c361d2, 0xc2e7661d,
|
||||
0x22d4ff8e, 0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2,
|
||||
0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d, 0xa1c9e0d6,
|
||||
0x346c4819, 0x61b76d87, 0x22540f2f, 0x2abe32e1, 0xaa54166b,
|
||||
0x22568e3a, 0xa2d341d0, 0x66db40c8, 0xa784392f, 0x004dff2f,
|
||||
0x2db9d2de, 0x97943fac, 0x4a97c1d8, 0x527644b7, 0xb5f437a7,
|
||||
0xb82cbaef, 0xd751d159, 0x6ff7f0ed, 0x5a097a1f, 0x827b68d0,
|
||||
0x90ecf52e, 0x22b0c054, 0xbc8e5935, 0x4b6d2f7f, 0x50bb64a2,
|
||||
0xd2664910, 0xbee5812d, 0xb7332290, 0xe93b159f, 0xb48ee411,
|
||||
0x4bff345d, 0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165,
|
||||
0xd5b1caad, 0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50, 0x882240f2,
|
||||
0x0c6e4f38, 0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f, 0xc59c5319,
|
||||
0xb949e354, 0xb04669fe, 0xb1b6ab8a, 0xc71358dd, 0x6385c545,
|
||||
0x110f935d, 0x57538ad5, 0x6a390493, 0xe63d37e0, 0x2a54f6b3,
|
||||
0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a, 0x29f9d4d5,
|
||||
0xf61b1891, 0xbb72275e, 0xaa508167, 0x38901091, 0xc6b505eb,
|
||||
0x84c7cb8c, 0x2ad75a0f, 0x874a1427, 0xa2d1936b, 0x2ad286af,
|
||||
0xaa56d291, 0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9,
|
||||
0x6c00b32d, 0x73e2bb14, 0xa0bebc3c, 0x54623779, 0x64459eab,
|
||||
0x3f328b82, 0x7718cf82, 0x59a2cea6, 0x04ee002e, 0x89fe78e6,
|
||||
0x3fab0950, 0x325ff6c2, 0x81383f05, 0x6963c5c8, 0x76cb5ad6,
|
||||
0xd49974c9, 0xca180dcf, 0x380782d5, 0xc7fa5cf6, 0x8ac31511,
|
||||
0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, 0x31366241,
|
||||
0x051ef495, 0xaa573b04, 0x4a805d8d, 0x548300d0, 0x00322a3c,
|
||||
0xbf64cddf, 0xba57a68e, 0x75c6372b, 0x50afd341, 0xa7c13275,
|
||||
0x915a0bf5, 0x6b54bfab, 0x2b0b1426, 0xab4cc9d7, 0x449ccd82,
|
||||
0xf7fbf265, 0xab85c5f3, 0x1b55db94, 0xaad4e324, 0xcfa4bd3f,
|
||||
0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, 0xeadf55b3, 0xd5bd9e98,
|
||||
0xe31231b2, 0x2ad5ad6c, 0x954329de, 0xadbe4528, 0xd8710f69,
|
||||
0xaa51c90f, 0xaa786bf6, 0x22513f1e, 0xaa51a79b, 0x2ad344cc,
|
||||
0x7b5a41f0, 0xd37cfbad, 0x1b069505, 0x41ece491, 0xb4c332e6,
|
||||
0x032268d4, 0xc9600acc, 0xce387e6d, 0xbf6bb16c, 0x6a70fb78,
|
||||
0x0d03d9c9, 0xd4df39de, 0xe01063da, 0x4736f464, 0x5ad328d8,
|
||||
0xb347cc96, 0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a,
|
||||
0xe11f0abc, 0xbfc5fe4a, 0xa70aec10, 0xac39570a, 0x3f04442f,
|
||||
0x6188b153, 0xe0397a2e, 0x5727cb79, 0x9ceb418f, 0x1cacd68d,
|
||||
0x2ad37c96, 0x0175cb9d, 0xc69dff09, 0xc75b65f0, 0xd9db40d8,
|
||||
0xec0e7779, 0x4744ead4, 0xb11c3274, 0xdd24cb9e, 0x7e1c54bd,
|
||||
0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755, 0xd47c27af,
|
||||
0x51c85f4d, 0x56907596, 0xa5bb15e6, 0x580304f0, 0xca042cf1,
|
||||
0x011a37ea, 0x8dbfaadb, 0x35ba3e4a, 0x3526ffa0, 0xc37b4d09,
|
||||
0xbc306ed9, 0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0,
|
||||
0x7c63b2cf, 0x700b45e1, 0xd5ea50f1, 0x85a92872, 0xaf1fbda7,
|
||||
0xd4234870, 0xa7870bf3, 0x2d3b4d79, 0x42e04198, 0x0cd0ede7,
|
||||
0x26470db8, 0xf881814c, 0x474d6ad7, 0x7c0c5e5c, 0xd1231959,
|
||||
0x381b7298, 0xf5d2f4db, 0xab838653, 0x6e2f1e23, 0x83719c9e,
|
||||
0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c,
|
||||
0xe1e696ff, 0xb141ab08, 0x7cca89b9, 0x1a69e783, 0x02cc4843,
|
||||
0xa2f7c579, 0x429ef47d, 0x427b169c, 0x5ac9f049, 0xdd8f0f00,
|
||||
0x5c8165bf };
|
||||
|
||||
static const uint32 S2[256] = {
|
||||
0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a,
|
||||
0xeec5207a, 0x55889c94, 0x72fc0651, 0xada7ef79, 0x4e1d7235,
|
||||
0xd55a63ce, 0xde0436ba, 0x99c430ef, 0x5f0c0794, 0x18dcdb7d,
|
||||
0xa1d6eff3, 0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909,
|
||||
0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb, 0xd1da4181,
|
||||
0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, 0x01420ddb, 0xe4e7ef5b,
|
||||
0x25a1ff41, 0xe180f806, 0x1fc41080, 0x179bee7a, 0xd37ac6a9,
|
||||
0xfe5830a4, 0x98de8b7f, 0x77e83f4e, 0x79929269, 0x24fa9f7b,
|
||||
0xe113c85b, 0xacc40083, 0xd7503525, 0xf7ea615f, 0x62143154,
|
||||
0x0d554b63, 0x5d681121, 0xc866c359, 0x3d63cf73, 0xcee234c0,
|
||||
0xd4d87e87, 0x5c672b21, 0x071f6181, 0x39f7627f, 0x361e3084,
|
||||
0xe4eb573b, 0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d,
|
||||
0x2701f50c, 0x99847ab4, 0xa0e3df79, 0xba6cf38c, 0x10843094,
|
||||
0x2537a95e, 0xf46f6ffe, 0xa1ff3b1f, 0x208cfb6a, 0x8f458c74,
|
||||
0xd9e0a227, 0x4ec73a34, 0xfc884f69, 0x3e4de8df, 0xef0e0088,
|
||||
0x3559648d, 0x8a45388c, 0x1d804366, 0x721d9bfd, 0xa58684bb,
|
||||
0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4, 0xce280ae1,
|
||||
0x27e19ba5, 0xd5a6c252, 0xe49754bd, 0xc5d655dd, 0xeb667064,
|
||||
0x77840b4d, 0xa1b6a801, 0x84db26a9, 0xe0b56714, 0x21f043b7,
|
||||
0xe5d05860, 0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755,
|
||||
0xb5625dbf, 0x68561be6, 0x83ca6b94, 0x2d6ed23b, 0xeccf01db,
|
||||
0xa6d3d0ba, 0xb6803d5c, 0xaf77a709, 0x33b4a34c, 0x397bc8d6,
|
||||
0x5ee22b95, 0x5f0e5304, 0x81ed6f61, 0x20e74364, 0xb45e1378,
|
||||
0xde18639b, 0x881ca122, 0xb96726d1, 0x8049a7e8, 0x22b7da7b,
|
||||
0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, 0x488cb402,
|
||||
0x1ba4fe5b, 0xa4b09f6b, 0x1ca815cf, 0xa20c3005, 0x8871df63,
|
||||
0xb9de2fcb, 0x0cc6c9e9, 0x0beeff53, 0xe3214517, 0xb4542835,
|
||||
0x9f63293c, 0xee41e729, 0x6e1d2d7c, 0x50045286, 0x1e6685f3,
|
||||
0xf33401c6, 0x30a22c95, 0x31a70850, 0x60930f13, 0x73f98417,
|
||||
0xa1269859, 0xec645c44, 0x52c877a9, 0xcdff33a6, 0xa02b1741,
|
||||
0x7cbad9a2, 0x2180036f, 0x50d99c08, 0xcb3f4861, 0xc26bd765,
|
||||
0x64a3f6ab, 0x80342676, 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6,
|
||||
0xcdf0b680, 0x17844d3b, 0x31eef84d, 0x7e0824e4, 0x2ccb49eb,
|
||||
0x846a3bae, 0x8ff77888, 0xee5d60f6, 0x7af75673, 0x2fdd5cdb,
|
||||
0xa11631c1, 0x30f66f43, 0xb3faec54, 0x157fd7fa, 0xef8579cc,
|
||||
0xd152de58, 0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8,
|
||||
0x99319ad5, 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906, 0xb8da230c,
|
||||
0x80823028, 0xdcdef3c8, 0xd35fb171, 0x088a1bc8, 0xbec0c560,
|
||||
0x61a3c9e8, 0xbca8f54d, 0xc72feffa, 0x22822e99, 0x82c570b4,
|
||||
0xd8d94e89, 0x8b1c34bc, 0x301e16e6, 0x273be979, 0xb0ffeaa6,
|
||||
0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b, 0x43daf65a,
|
||||
0xf7e19798, 0x7619b72f, 0x8f1c9ba4, 0xdc8637a0, 0x16a7d3b1,
|
||||
0x9fc393b7, 0xa7136eeb, 0xc6bcc63e, 0x1a513742, 0xef6828bc,
|
||||
0x520365d6, 0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e,
|
||||
0xdb92f2fb, 0x5eea29cb, 0x145892f5, 0x91584f7f, 0x5483697b,
|
||||
0x2667a8cc, 0x85196048, 0x8c4bacea, 0x833860d4, 0x0d23e0f9,
|
||||
0x6c387e8a, 0x0ae6d249, 0xb284600c, 0xd835731d, 0xdcb1c647,
|
||||
0xac4c56ea, 0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa,
|
||||
0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589,
|
||||
0xa345415e, 0x5c038323, 0x3e5d3bb9, 0x43d79572, 0x7e6dd07c,
|
||||
0x06dfdf1e, 0x6c6cc4ef, 0x7160a539, 0x73bfbe70, 0x83877605,
|
||||
0x4523ecf1 };
|
||||
|
||||
static const uint32 S3[256] = {
|
||||
0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff,
|
||||
0x369fe44b, 0x8c1fc644, 0xaececa90, 0xbeb1f9bf, 0xeefbcaea,
|
||||
0xe8cf1950, 0x51df07ae, 0x920e8806, 0xf0ad0548, 0xe13c8d83,
|
||||
0x927010d5, 0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e,
|
||||
0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e, 0x553fb2c0,
|
||||
0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee, 0x825b1bfd,
|
||||
0x9255c5ed, 0x1257a240, 0x4e1a8302, 0xbae07fff, 0x528246e7,
|
||||
0x8e57140e, 0x3373f7bf, 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5,
|
||||
0xa8c01db7, 0x579fc264, 0x67094f31, 0xf2bd3f5f, 0x40fff7c1,
|
||||
0x1fb78dfc, 0x8e6bd2c1, 0x437be59b, 0x99b03dbf, 0xb5dbc64b,
|
||||
0x638dc0e6, 0x55819d99, 0xa197c81c, 0x4a012d6e, 0xc5884a28,
|
||||
0xccc36f71, 0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f,
|
||||
0x2f7fe850, 0xd7c07f7e, 0x02507fbf, 0x5afb9a04, 0xa747d2d0,
|
||||
0x1651192e, 0xaf70bf3e, 0x58c31380, 0x5f98302e, 0x727cc3c4,
|
||||
0x0a0fb402, 0x0f7fef82, 0x8c96fdad, 0x5d2c2aae, 0x8ee99a49,
|
||||
0x50da88b8, 0x8427f4a0, 0x1eac5790, 0x796fb449, 0x8252dc15,
|
||||
0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504, 0xfa5d7403,
|
||||
0xe83ec305, 0x4f91751a, 0x925669c2, 0x23efe941, 0xa903f12e,
|
||||
0x60270df2, 0x0276e4b6, 0x94fd6574, 0x927985b2, 0x8276dbcb,
|
||||
0x02778176, 0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e,
|
||||
0x842f7d83, 0x340ce5c8, 0x96bbb682, 0x93b4b148, 0xef303cab,
|
||||
0x984faf28, 0x779faf9b, 0x92dc560d, 0x224d1e20, 0x8437aa88,
|
||||
0x7d29dc96, 0x2756d3dc, 0x8b907cee, 0xb51fd240, 0xe7c07ce3,
|
||||
0xe566b4a1, 0xc3e9615e, 0x3cf8209d, 0x6094d1e3, 0xcd9ca341,
|
||||
0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9,
|
||||
0xbda8229c, 0x127dadaa, 0x438a074e, 0x1f97c090, 0x081bdb8a,
|
||||
0x93a07ebe, 0xb938ca15, 0x97b03cff, 0x3dc2c0f8, 0x8d1ab2ec,
|
||||
0x64380e51, 0x68cc7bfb, 0xd90f2788, 0x12490181, 0x5de5ffd4,
|
||||
0xdd7ef86a, 0x76a2e214, 0xb9a40368, 0x925d958f, 0x4b39fffa,
|
||||
0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623, 0x193cbcfa,
|
||||
0x27627545, 0x825cf47a, 0x61bd8ba0, 0xd11e42d1, 0xcead04f4,
|
||||
0x127ea392, 0x10428db7, 0x8272a972, 0x9270c4a8, 0x127de50b,
|
||||
0x285ba1c8, 0x3c62f44f, 0x35c0eaa5, 0xe805d231, 0x428929fb,
|
||||
0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b, 0x1f081fab, 0x108618ae,
|
||||
0xfcfd086d, 0xf9ff2889, 0x694bcc11, 0x236a5cae, 0x12deca4d,
|
||||
0x2c3f8cc5, 0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67,
|
||||
0x494a488c, 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45, 0x3a609437,
|
||||
0xec00c9a9, 0x44715253, 0x0a874b49, 0xd773bc40, 0x7c34671c,
|
||||
0x02717ef6, 0x4feb5536, 0xa2d02fff, 0xd2bf60c4, 0xd43f03c0,
|
||||
0x50b4ef6d, 0x07478cd1, 0x006e1888, 0xa2e53f55, 0xb9e6d4bc,
|
||||
0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d, 0x72f87b33,
|
||||
0xabcc4f33, 0x7688c55d, 0x7b00a6b0, 0x947b0001, 0x570075d2,
|
||||
0xf9bb88f8, 0x8942019e, 0x4264a5ff, 0x856302e0, 0x72dbd92b,
|
||||
0xee971b69, 0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767,
|
||||
0xcf1febd2, 0x61efc8c2, 0xf1ac2571, 0xcc8239c2, 0x67214cb8,
|
||||
0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, 0xf90a5c38, 0x0ff0443d,
|
||||
0x606e6dc6, 0x60543a49, 0x5727c148, 0x2be98a1d, 0x8ab41738,
|
||||
0x20e1be24, 0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d,
|
||||
0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31,
|
||||
0x9c305a00, 0x52bce688, 0x1b03588a, 0xf7baefd5, 0x4142ed9c,
|
||||
0xa4315c11, 0x83323ec5, 0xdfef4636, 0xa133c501, 0xe9d3531c,
|
||||
0xee353783 };
|
||||
|
||||
static const uint32 S4[256] = {
|
||||
0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb,
|
||||
0x64ad8c57, 0x85510443, 0xfa020ed1, 0x7e287aff, 0xe60fb663,
|
||||
0x095f35a1, 0x79ebf120, 0xfd059d43, 0x6497b7b1, 0xf3641f63,
|
||||
0x241e4adf, 0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220,
|
||||
0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15, 0xee4d111a,
|
||||
0x0fca5167, 0x71ff904c, 0x2d195ffe, 0x1a05645f, 0x0c13fefe,
|
||||
0x081b08ca, 0x05170121, 0x80530100, 0xe83e5efe, 0xac9af4f8,
|
||||
0x7fe72701, 0xd2b8ee5f, 0x06df4261, 0xbb9e9b8a, 0x7293ea25,
|
||||
0xce84ffdf, 0xf5718801, 0x3dd64b04, 0xa26f263b, 0x7ed48400,
|
||||
0x547eebe6, 0x446d4ca0, 0x6cf3d6f5, 0x2649abdf, 0xaea0c7f5,
|
||||
0x36338cc1, 0x503f7e93, 0xd3772061, 0x11b638e1, 0x72500e03,
|
||||
0xf80eb2bb, 0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746,
|
||||
0xc9335400, 0x6920318f, 0x081dbb99, 0xffc304a5, 0x4d351805,
|
||||
0x7f3d5ce3, 0xa6c866c6, 0x5d5bcca9, 0xdaec6fea, 0x9f926f91,
|
||||
0x9f46222f, 0x3991467d, 0xa5bf6d8e, 0x1143c44f, 0x43958302,
|
||||
0xd0214eeb, 0x022083b8, 0x3fb6180c, 0x18f8931e, 0x281658e6,
|
||||
0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c, 0xf32d0a25,
|
||||
0x79098b02, 0xe4eabb81, 0x28123b23, 0x69dead38, 0x1574ca16,
|
||||
0xdf871b62, 0x211c40b7, 0xa51a9ef9, 0x0014377b, 0x041e8ac8,
|
||||
0x09114003, 0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340,
|
||||
0x557be8de, 0x00eae4a7, 0x0ce5c2ec, 0x4db4bba6, 0xe756bdff,
|
||||
0xdd3369ac, 0xec17b035, 0x06572327, 0x99afc8b0, 0x56c8c391,
|
||||
0x6b65811c, 0x5e146119, 0x6e85cb75, 0xbe07c002, 0xc2325577,
|
||||
0x893ff4ec, 0x5bbfc92d, 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24,
|
||||
0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, 0xaac9548a,
|
||||
0xeca1d7c7, 0x041afa32, 0x1d16625a, 0x6701902c, 0x9b757a54,
|
||||
0x31d477f7, 0x9126b031, 0x36cc6fdb, 0xc70b8b46, 0xd9e66a48,
|
||||
0x56e55a79, 0x026a4ceb, 0x52437eff, 0x2f8f76b4, 0x0df980a5,
|
||||
0x8674cde3, 0xedda04eb, 0x17a9be04, 0x2c18f4df, 0xb7747f9d,
|
||||
0xab2af7b4, 0xefc34d20, 0x2e096b7c, 0x1741a254, 0xe5b6a035,
|
||||
0x213d42f6, 0x2c1c7c26, 0x61c2f50f, 0x6552daf9, 0xd2c231f8,
|
||||
0x25130f69, 0xd8167fa2, 0x0418f2c8, 0x001a96a6, 0x0d1526ab,
|
||||
0x63315c21, 0x5e0a72ec, 0x49bafefd, 0x187908d9, 0x8d0dbd86,
|
||||
0x311170a7, 0x3e9b640c, 0xcc3e10d7, 0xd5cad3b6, 0x0caec388,
|
||||
0xf73001e1, 0x6c728aff, 0x71eae2a1, 0x1f9af36e, 0xcfcbd12f,
|
||||
0xc1de8417, 0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3,
|
||||
0xb1c52fca, 0xb4be31cd, 0xd8782806, 0x12a3a4e2, 0x6f7de532,
|
||||
0x58fd7eb6, 0xd01ee900, 0x24adffc2, 0xf4990fc5, 0x9711aac5,
|
||||
0x001d7b95, 0x82e5e7d2, 0x109873f6, 0x00613096, 0xc32d9521,
|
||||
0xada121ff, 0x29908415, 0x7fbb977f, 0xaf9eb3db, 0x29c9ed2a,
|
||||
0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091, 0xd49e2ce7,
|
||||
0x0ce454a9, 0xd60acd86, 0x015f1919, 0x77079103, 0xdea03af6,
|
||||
0x78a8565e, 0xdee356df, 0x21f05cbe, 0x8b75e387, 0xb3c50651,
|
||||
0xb8a5c3ef, 0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf,
|
||||
0xafe67afb, 0xf470c4b2, 0xf3e0eb5b, 0xd6cc9876, 0x39e4460c,
|
||||
0x1fda8538, 0x1987832f, 0xca007367, 0xa99144f8, 0x296b299e,
|
||||
0x492fc295, 0x9266beab, 0xb5676e69, 0x9bd3ddda, 0xdf7e052f,
|
||||
0xdb25701c, 0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04,
|
||||
0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979,
|
||||
0x932bcdf6, 0xb657c34d, 0x4edfd282, 0x7ae5290c, 0x3cb9536b,
|
||||
0x851e20fe, 0x9833557e, 0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1,
|
||||
0x0aef7ed2 };
|
||||
|
||||
static const uint32 S5[256] = {
|
||||
0x7ec90c04, 0x2c6e74b9, 0x9b0e66df, 0xa6337911, 0xb86a7fff,
|
||||
0x1dd358f5, 0x44dd9d44, 0x1731167f, 0x08fbf1fa, 0xe7f511cc,
|
||||
0xd2051b00, 0x735aba00, 0x2ab722d8, 0x386381cb, 0xacf6243a,
|
||||
0x69befd7a, 0xe6a2e77f, 0xf0c720cd, 0xc4494816, 0xccf5c180,
|
||||
0x38851640, 0x15b0a848, 0xe68b18cb, 0x4caadeff, 0x5f480a01,
|
||||
0x0412b2aa, 0x259814fc, 0x41d0efe2, 0x4e40b48d, 0x248eb6fb,
|
||||
0x8dba1cfe, 0x41a99b02, 0x1a550a04, 0xba8f65cb, 0x7251f4e7,
|
||||
0x95a51725, 0xc106ecd7, 0x97a5980a, 0xc539b9aa, 0x4d79fe6a,
|
||||
0xf2f3f763, 0x68af8040, 0xed0c9e56, 0x11b4958b, 0xe1eb5a88,
|
||||
0x8709e6b0, 0xd7e07156, 0x4e29fea7, 0x6366e52d, 0x02d1c000,
|
||||
0xc4ac8e05, 0x9377f571, 0x0c05372a, 0x578535f2, 0x2261be02,
|
||||
0xd642a0c9, 0xdf13a280, 0x74b55bd2, 0x682199c0, 0xd421e5ec,
|
||||
0x53fb3ce8, 0xc8adedb3, 0x28a87fc9, 0x3d959981, 0x5c1ff900,
|
||||
0xfe38d399, 0x0c4eff0b, 0x062407ea, 0xaa2f4fb1, 0x4fb96976,
|
||||
0x90c79505, 0xb0a8a774, 0xef55a1ff, 0xe59ca2c2, 0xa6b62d27,
|
||||
0xe66a4263, 0xdf65001f, 0x0ec50966, 0xdfdd55bc, 0x29de0655,
|
||||
0x911e739a, 0x17af8975, 0x32c7911c, 0x89f89468, 0x0d01e980,
|
||||
0x524755f4, 0x03b63cc9, 0x0cc844b2, 0xbcf3f0aa, 0x87ac36e9,
|
||||
0xe53a7426, 0x01b3d82b, 0x1a9e7449, 0x64ee2d7e, 0xcddbb1da,
|
||||
0x01c94910, 0xb868bf80, 0x0d26f3fd, 0x9342ede7, 0x04a5c284,
|
||||
0x636737b6, 0x50f5b616, 0xf24766e3, 0x8eca36c1, 0x136e05db,
|
||||
0xfef18391, 0xfb887a37, 0xd6e7f7d4, 0xc7fb7dc9, 0x3063fcdf,
|
||||
0xb6f589de, 0xec2941da, 0x26e46695, 0xb7566419, 0xf654efc5,
|
||||
0xd08d58b7, 0x48925401, 0xc1bacb7f, 0xe5ff550f, 0xb6083049,
|
||||
0x5bb5d0e8, 0x87d72e5a, 0xab6a6ee1, 0x223a66ce, 0xc62bf3cd,
|
||||
0x9e0885f9, 0x68cb3e47, 0x086c010f, 0xa21de820, 0xd18b69de,
|
||||
0xf3f65777, 0xfa02c3f6, 0x407edac3, 0xcbb3d550, 0x1793084d,
|
||||
0xb0d70eba, 0x0ab378d5, 0xd951fb0c, 0xded7da56, 0x4124bbe4,
|
||||
0x94ca0b56, 0x0f5755d1, 0xe0e1e56e, 0x6184b5be, 0x580a249f,
|
||||
0x94f74bc0, 0xe327888e, 0x9f7b5561, 0xc3dc0280, 0x05687715,
|
||||
0x646c6bd7, 0x44904db3, 0x66b4f0a3, 0xc0f1648a, 0x697ed5af,
|
||||
0x49e92ff6, 0x309e374f, 0x2cb6356a, 0x85808573, 0x4991f840,
|
||||
0x76f0ae02, 0x083be84d, 0x28421c9a, 0x44489406, 0x736e4cb8,
|
||||
0xc1092910, 0x8bc95fc6, 0x7d869cf4, 0x134f616f, 0x2e77118d,
|
||||
0xb31b2be1, 0xaa90b472, 0x3ca5d717, 0x7d161bba, 0x9cad9010,
|
||||
0xaf462ba2, 0x9fe459d2, 0x45d34559, 0xd9f2da13, 0xdbc65487,
|
||||
0xf3e4f94e, 0x176d486f, 0x097c13ea, 0x631da5c7, 0x445f7382,
|
||||
0x175683f4, 0xcdc66a97, 0x70be0288, 0xb3cdcf72, 0x6e5dd2f3,
|
||||
0x20936079, 0x459b80a5, 0xbe60e2db, 0xa9c23101, 0xeba5315c,
|
||||
0x224e42f2, 0x1c5c1572, 0xf6721b2c, 0x1ad2fff3, 0x8c25404e,
|
||||
0x324ed72f, 0x4067b7fd, 0x0523138e, 0x5ca3bc78, 0xdc0fd66e,
|
||||
0x75922283, 0x784d6b17, 0x58ebb16e, 0x44094f85, 0x3f481d87,
|
||||
0xfcfeae7b, 0x77b5ff76, 0x8c2302bf, 0xaaf47556, 0x5f46b02a,
|
||||
0x2b092801, 0x3d38f5f7, 0x0ca81f36, 0x52af4a8a, 0x66d5e7c0,
|
||||
0xdf3b0874, 0x95055110, 0x1b5ad7a8, 0xf61ed5ad, 0x6cf6e479,
|
||||
0x20758184, 0xd0cefa65, 0x88f7be58, 0x4a046826, 0x0ff6f8f3,
|
||||
0xa09c7f70, 0x5346aba0, 0x5ce96c28, 0xe176eda3, 0x6bac307f,
|
||||
0x376829d2, 0x85360fa9, 0x17e3fe2a, 0x24b79767, 0xf5a96b20,
|
||||
0xd6cd2595, 0x68ff1ebf, 0x7555442c, 0xf19f06be, 0xf9e0659a,
|
||||
0xeeb9491d, 0x34010718, 0xbb30cab8, 0xe822fe15, 0x88570983,
|
||||
0x750e6249, 0xda627e55, 0x5e76ffa8, 0xb1534546, 0x6d47de08,
|
||||
0xefe9e7d4 };
|
||||
|
||||
static const uint32 S6[256] = {
|
||||
0xf6fa8f9d, 0x2cac6ce1, 0x4ca34867, 0xe2337f7c, 0x95db08e7,
|
||||
0x016843b4, 0xeced5cbc, 0x325553ac, 0xbf9f0960, 0xdfa1e2ed,
|
||||
0x83f0579d, 0x63ed86b9, 0x1ab6a6b8, 0xde5ebe39, 0xf38ff732,
|
||||
0x8989b138, 0x33f14961, 0xc01937bd, 0xf506c6da, 0xe4625e7e,
|
||||
0xa308ea99, 0x4e23e33c, 0x79cbd7cc, 0x48a14367, 0xa3149619,
|
||||
0xfec94bd5, 0xa114174a, 0xeaa01866, 0xa084db2d, 0x09a8486f,
|
||||
0xa888614a, 0x2900af98, 0x01665991, 0xe1992863, 0xc8f30c60,
|
||||
0x2e78ef3c, 0xd0d51932, 0xcf0fec14, 0xf7ca07d2, 0xd0a82072,
|
||||
0xfd41197e, 0x9305a6b0, 0xe86be3da, 0x74bed3cd, 0x372da53c,
|
||||
0x4c7f4448, 0xdab5d440, 0x6dba0ec3, 0x083919a7, 0x9fbaeed9,
|
||||
0x49dbcfb0, 0x4e670c53, 0x5c3d9c01, 0x64bdb941, 0x2c0e636a,
|
||||
0xba7dd9cd, 0xea6f7388, 0xe70bc762, 0x35f29adb, 0x5c4cdd8d,
|
||||
0xf0d48d8c, 0xb88153e2, 0x08a19866, 0x1ae2eac8, 0x284caf89,
|
||||
0xaa928223, 0x9334be53, 0x3b3a21bf, 0x16434be3, 0x9aea3906,
|
||||
0xefe8c36e, 0xf890cdd9, 0x80226dae, 0xc340a4a3, 0xdf7e9c09,
|
||||
0xa694a807, 0x5b7c5ecc, 0x221db3a6, 0x9a69a02f, 0x68818a54,
|
||||
0xceb2296f, 0x53c0843a, 0xfe893655, 0x25bfe68a, 0xb4628abc,
|
||||
0xcf222ebf, 0x25ac6f48, 0xa9a99387, 0x53bddb65, 0xe76ffbe7,
|
||||
0xe967fd78, 0x0ba93563, 0x8e342bc1, 0xe8a11be9, 0x4980740d,
|
||||
0xc8087dfc, 0x8de4bf99, 0xa11101a0, 0x7fd37975, 0xda5a26c0,
|
||||
0xe81f994f, 0x9528cd89, 0xfd339fed, 0xb87834bf, 0x5f04456d,
|
||||
0x22258698, 0xc9c4c83b, 0x2dc156be, 0x4f628daa, 0x57f55ec5,
|
||||
0xe2220abe, 0xd2916ebf, 0x4ec75b95, 0x24f2c3c0, 0x42d15d99,
|
||||
0xcd0d7fa0, 0x7b6e27ff, 0xa8dc8af0, 0x7345c106, 0xf41e232f,
|
||||
0x35162386, 0xe6ea8926, 0x3333b094, 0x157ec6f2, 0x372b74af,
|
||||
0x692573e4, 0xe9a9d848, 0xf3160289, 0x3a62ef1d, 0xa787e238,
|
||||
0xf3a5f676, 0x74364853, 0x20951063, 0x4576698d, 0xb6fad407,
|
||||
0x592af950, 0x36f73523, 0x4cfb6e87, 0x7da4cec0, 0x6c152daa,
|
||||
0xcb0396a8, 0xc50dfe5d, 0xfcd707ab, 0x0921c42f, 0x89dff0bb,
|
||||
0x5fe2be78, 0x448f4f33, 0x754613c9, 0x2b05d08d, 0x48b9d585,
|
||||
0xdc049441, 0xc8098f9b, 0x7dede786, 0xc39a3373, 0x42410005,
|
||||
0x6a091751, 0x0ef3c8a6, 0x890072d6, 0x28207682, 0xa9a9f7be,
|
||||
0xbf32679d, 0xd45b5b75, 0xb353fd00, 0xcbb0e358, 0x830f220a,
|
||||
0x1f8fb214, 0xd372cf08, 0xcc3c4a13, 0x8cf63166, 0x061c87be,
|
||||
0x88c98f88, 0x6062e397, 0x47cf8e7a, 0xb6c85283, 0x3cc2acfb,
|
||||
0x3fc06976, 0x4e8f0252, 0x64d8314d, 0xda3870e3, 0x1e665459,
|
||||
0xc10908f0, 0x513021a5, 0x6c5b68b7, 0x822f8aa0, 0x3007cd3e,
|
||||
0x74719eef, 0xdc872681, 0x073340d4, 0x7e432fd9, 0x0c5ec241,
|
||||
0x8809286c, 0xf592d891, 0x08a930f6, 0x957ef305, 0xb7fbffbd,
|
||||
0xc266e96f, 0x6fe4ac98, 0xb173ecc0, 0xbc60b42a, 0x953498da,
|
||||
0xfba1ae12, 0x2d4bd736, 0x0f25faab, 0xa4f3fceb, 0xe2969123,
|
||||
0x257f0c3d, 0x9348af49, 0x361400bc, 0xe8816f4a, 0x3814f200,
|
||||
0xa3f94043, 0x9c7a54c2, 0xbc704f57, 0xda41e7f9, 0xc25ad33a,
|
||||
0x54f4a084, 0xb17f5505, 0x59357cbe, 0xedbd15c8, 0x7f97c5ab,
|
||||
0xba5ac7b5, 0xb6f6deaf, 0x3a479c3a, 0x5302da25, 0x653d7e6a,
|
||||
0x54268d49, 0x51a477ea, 0x5017d55b, 0xd7d25d88, 0x44136c76,
|
||||
0x0404a8c8, 0xb8e5a121, 0xb81a928a, 0x60ed5869, 0x97c55b96,
|
||||
0xeaec991b, 0x29935913, 0x01fdb7f1, 0x088e8dfa, 0x9ab6f6f5,
|
||||
0x3b4cbf9f, 0x4a5de3ab, 0xe6051d35, 0xa0e1d855, 0xd36b4cf1,
|
||||
0xf544edeb, 0xb0e93524, 0xbebb8fbd, 0xa2d762cf, 0x49c92f54,
|
||||
0x38b5f331, 0x7128a454, 0x48392905, 0xa65b1db8, 0x851c97bd,
|
||||
0xd675cf2f };
|
||||
|
||||
static const uint32 S7[256] = {
|
||||
0x85e04019, 0x332bf567, 0x662dbfff, 0xcfc65693, 0x2a8d7f6f,
|
||||
0xab9bc912, 0xde6008a1, 0x2028da1f, 0x0227bce7, 0x4d642916,
|
||||
0x18fac300, 0x50f18b82, 0x2cb2cb11, 0xb232e75c, 0x4b3695f2,
|
||||
0xb28707de, 0xa05fbcf6, 0xcd4181e9, 0xe150210c, 0xe24ef1bd,
|
||||
0xb168c381, 0xfde4e789, 0x5c79b0d8, 0x1e8bfd43, 0x4d495001,
|
||||
0x38be4341, 0x913cee1d, 0x92a79c3f, 0x089766be, 0xbaeeadf4,
|
||||
0x1286becf, 0xb6eacb19, 0x2660c200, 0x7565bde4, 0x64241f7a,
|
||||
0x8248dca9, 0xc3b3ad66, 0x28136086, 0x0bd8dfa8, 0x356d1cf2,
|
||||
0x107789be, 0xb3b2e9ce, 0x0502aa8f, 0x0bc0351e, 0x166bf52a,
|
||||
0xeb12ff82, 0xe3486911, 0xd34d7516, 0x4e7b3aff, 0x5f43671b,
|
||||
0x9cf6e037, 0x4981ac83, 0x334266ce, 0x8c9341b7, 0xd0d854c0,
|
||||
0xcb3a6c88, 0x47bc2829, 0x4725ba37, 0xa66ad22b, 0x7ad61f1e,
|
||||
0x0c5cbafa, 0x4437f107, 0xb6e79962, 0x42d2d816, 0x0a961288,
|
||||
0xe1a5c06e, 0x13749e67, 0x72fc081a, 0xb1d139f7, 0xf9583745,
|
||||
0xcf19df58, 0xbec3f756, 0xc06eba30, 0x07211b24, 0x45c28829,
|
||||
0xc95e317f, 0xbc8ec511, 0x38bc46e9, 0xc6e6fa14, 0xbae8584a,
|
||||
0xad4ebc46, 0x468f508b, 0x7829435f, 0xf124183b, 0x821dba9f,
|
||||
0xaff60ff4, 0xea2c4e6d, 0x16e39264, 0x92544a8b, 0x009b4fc3,
|
||||
0xaba68ced, 0x9ac96f78, 0x06a5b79a, 0xb2856e6e, 0x1aec3ca9,
|
||||
0xbe838688, 0x0e0804e9, 0x55f1be56, 0xe7e5363b, 0xb3a1f25d,
|
||||
0xf7debb85, 0x61fe033c, 0x16746233, 0x3c034c28, 0xda6d0c74,
|
||||
0x79aac56c, 0x3ce4e1ad, 0x51f0c802, 0x98f8f35a, 0x1626a49f,
|
||||
0xeed82b29, 0x1d382fe3, 0x0c4fb99a, 0xbb325778, 0x3ec6d97b,
|
||||
0x6e77a6a9, 0xcb658b5c, 0xd45230c7, 0x2bd1408b, 0x60c03eb7,
|
||||
0xb9068d78, 0xa33754f4, 0xf430c87d, 0xc8a71302, 0xb96d8c32,
|
||||
0xebd4e7be, 0xbe8b9d2d, 0x7979fb06, 0xe7225308, 0x8b75cf77,
|
||||
0x11ef8da4, 0xe083c858, 0x8d6b786f, 0x5a6317a6, 0xfa5cf7a0,
|
||||
0x5dda0033, 0xf28ebfb0, 0xf5b9c310, 0xa0eac280, 0x08b9767a,
|
||||
0xa3d9d2b0, 0x79d34217, 0x021a718d, 0x9ac6336a, 0x2711fd60,
|
||||
0x438050e3, 0x069908a8, 0x3d7fedc4, 0x826d2bef, 0x4eeb8476,
|
||||
0x488dcf25, 0x36c9d566, 0x28e74e41, 0xc2610aca, 0x3d49a9cf,
|
||||
0xbae3b9df, 0xb65f8de6, 0x92aeaf64, 0x3ac7d5e6, 0x9ea80509,
|
||||
0xf22b017d, 0xa4173f70, 0xdd1e16c3, 0x15e0d7f9, 0x50b1b887,
|
||||
0x2b9f4fd5, 0x625aba82, 0x6a017962, 0x2ec01b9c, 0x15488aa9,
|
||||
0xd716e740, 0x40055a2c, 0x93d29a22, 0xe32dbf9a, 0x058745b9,
|
||||
0x3453dc1e, 0xd699296e, 0x496cff6f, 0x1c9f4986, 0xdfe2ed07,
|
||||
0xb87242d1, 0x19de7eae, 0x053e561a, 0x15ad6f8c, 0x66626c1c,
|
||||
0x7154c24c, 0xea082b2a, 0x93eb2939, 0x17dcb0f0, 0x58d4f2ae,
|
||||
0x9ea294fb, 0x52cf564c, 0x9883fe66, 0x2ec40581, 0x763953c3,
|
||||
0x01d6692e, 0xd3a0c108, 0xa1e7160e, 0xe4f2dfa6, 0x693ed285,
|
||||
0x74904698, 0x4c2b0edd, 0x4f757656, 0x5d393378, 0xa132234f,
|
||||
0x3d321c5d, 0xc3f5e194, 0x4b269301, 0xc79f022f, 0x3c997e7e,
|
||||
0x5e4f9504, 0x3ffafbbd, 0x76f7ad0e, 0x296693f4, 0x3d1fce6f,
|
||||
0xc61e45be, 0xd3b5ab34, 0xf72bf9b7, 0x1b0434c0, 0x4e72b567,
|
||||
0x5592a33d, 0xb5229301, 0xcfd2a87f, 0x60aeb767, 0x1814386b,
|
||||
0x30bcc33d, 0x38a0c07d, 0xfd1606f2, 0xc363519b, 0x589dd390,
|
||||
0x5479f8e6, 0x1cb8d647, 0x97fd61a9, 0xea7759f4, 0x2d57539d,
|
||||
0x569a58cf, 0xe84e63ad, 0x462e1b78, 0x6580f87e, 0xf3817914,
|
||||
0x91da55f4, 0x40a230f3, 0xd1988f35, 0xb6e318d2, 0x3ffa50bc,
|
||||
0x3d40f021, 0xc3c0bdae, 0x4958c24c, 0x518f36b2, 0x84b1d370,
|
||||
0x0fedce83, 0x878ddada, 0xf2a279c7, 0x94e01be8, 0x90716f4b,
|
||||
0x954b8aa3 };
|
||||
|
||||
static const uint32 S8[256] = {
|
||||
0xe216300d, 0xbbddfffc, 0xa7ebdabd, 0x35648095, 0x7789f8b7,
|
||||
0xe6c1121b, 0x0e241600, 0x052ce8b5, 0x11a9cfb0, 0xe5952f11,
|
||||
0xece7990a, 0x9386d174, 0x2a42931c, 0x76e38111, 0xb12def3a,
|
||||
0x37ddddfc, 0xde9adeb1, 0x0a0cc32c, 0xbe197029, 0x84a00940,
|
||||
0xbb243a0f, 0xb4d137cf, 0xb44e79f0, 0x049eedfd, 0x0b15a15d,
|
||||
0x480d3168, 0x8bbbde5a, 0x669ded42, 0xc7ece831, 0x3f8f95e7,
|
||||
0x72df191b, 0x7580330d, 0x94074251, 0x5c7dcdfa, 0xabbe6d63,
|
||||
0xaa402164, 0xb301d40a, 0x02e7d1ca, 0x53571dae, 0x7a3182a2,
|
||||
0x12a8ddec, 0xfdaa335d, 0x176f43e8, 0x71fb46d4, 0x38129022,
|
||||
0xce949ad4, 0xb84769ad, 0x965bd862, 0x82f3d055, 0x66fb9767,
|
||||
0x15b80b4e, 0x1d5b47a0, 0x4cfde06f, 0xc28ec4b8, 0x57e8726e,
|
||||
0x647a78fc, 0x99865d44, 0x608bd593, 0x6c200e03, 0x39dc5ff6,
|
||||
0x5d0b00a3, 0xae63aff2, 0x7e8bd632, 0x70108c0c, 0xbbd35049,
|
||||
0x2998df04, 0x980cf42a, 0x9b6df491, 0x9e7edd53, 0x06918548,
|
||||
0x58cb7e07, 0x3b74ef2e, 0x522fffb1, 0xd24708cc, 0x1c7e27cd,
|
||||
0xa4eb215b, 0x3cf1d2e2, 0x19b47a38, 0x424f7618, 0x35856039,
|
||||
0x9d17dee7, 0x27eb35e6, 0xc9aff67b, 0x36baf5b8, 0x09c467cd,
|
||||
0xc18910b1, 0xe11dbf7b, 0x06cd1af8, 0x7170c608, 0x2d5e3354,
|
||||
0xd4de495a, 0x64c6d006, 0xbcc0c62c, 0x3dd00db3, 0x708f8f34,
|
||||
0x77d51b42, 0x264f620f, 0x24b8d2bf, 0x15c1b79e, 0x46a52564,
|
||||
0xf8d7e54e, 0x3e378160, 0x7895cda5, 0x859c15a5, 0xe6459788,
|
||||
0xc37bc75f, 0xdb07ba0c, 0x0676a3ab, 0x7f229b1e, 0x31842e7b,
|
||||
0x24259fd7, 0xf8bef472, 0x835ffcb8, 0x6df4c1f2, 0x96f5b195,
|
||||
0xfd0af0fc, 0xb0fe134c, 0xe2506d3d, 0x4f9b12ea, 0xf215f225,
|
||||
0xa223736f, 0x9fb4c428, 0x25d04979, 0x34c713f8, 0xc4618187,
|
||||
0xea7a6e98, 0x7cd16efc, 0x1436876c, 0xf1544107, 0xbedeee14,
|
||||
0x56e9af27, 0xa04aa441, 0x3cf7c899, 0x92ecbae6, 0xdd67016d,
|
||||
0x151682eb, 0xa842eedf, 0xfdba60b4, 0xf1907b75, 0x20e3030f,
|
||||
0x24d8c29e, 0xe139673b, 0xefa63fb8, 0x71873054, 0xb6f2cf3b,
|
||||
0x9f326442, 0xcb15a4cc, 0xb01a4504, 0xf1e47d8d, 0x844a1be5,
|
||||
0xbae7dfdc, 0x42cbda70, 0xcd7dae0a, 0x57e85b7a, 0xd53f5af6,
|
||||
0x20cf4d8c, 0xcea4d428, 0x79d130a4, 0x3486ebfb, 0x33d3cddc,
|
||||
0x77853b53, 0x37effcb5, 0xc5068778, 0xe580b3e6, 0x4e68b8f4,
|
||||
0xc5c8b37e, 0x0d809ea2, 0x398feb7c, 0x132a4f94, 0x43b7950e,
|
||||
0x2fee7d1c, 0x223613bd, 0xdd06caa2, 0x37df932b, 0xc4248289,
|
||||
0xacf3ebc3, 0x5715f6b7, 0xef3478dd, 0xf267616f, 0xc148cbe4,
|
||||
0x9052815e, 0x5e410fab, 0xb48a2465, 0x2eda7fa4, 0xe87b40e4,
|
||||
0xe98ea084, 0x5889e9e1, 0xefd390fc, 0xdd07d35b, 0xdb485694,
|
||||
0x38d7e5b2, 0x57720101, 0x730edebc, 0x5b643113, 0x94917e4f,
|
||||
0x503c2fba, 0x646f1282, 0x7523d24a, 0xe0779695, 0xf9c17a8f,
|
||||
0x7a5b2121, 0xd187b896, 0x29263a4d, 0xba510cdf, 0x81f47c9f,
|
||||
0xad1163ed, 0xea7b5965, 0x1a00726e, 0x11403092, 0x00da6d77,
|
||||
0x4a0cdd61, 0xad1f4603, 0x605bdfb0, 0x9eedc364, 0x22ebe6a8,
|
||||
0xcee7d28a, 0xa0e736a0, 0x5564a6b9, 0x10853209, 0xc7eb8f37,
|
||||
0x2de705ca, 0x8951570f, 0xdf09822b, 0xbd691a6c, 0xaa12e4f2,
|
||||
0x87451c0f, 0xe0f6a27a, 0x3ada4819, 0x4cf1764f, 0x0d771c2b,
|
||||
0x67cdb156, 0x350d8384, 0x5938fa0f, 0x42399ef3, 0x36997b07,
|
||||
0x0e84093d, 0x4aa93e61, 0x8360d87b, 0x1fa98b0c, 0x1149382c,
|
||||
0xe97625a5, 0x0614d1b7, 0x0e25244b, 0x0c768347, 0x589e8d82,
|
||||
0x0d2059d1, 0xa466bb1e, 0xf8da0a82, 0x04f19130, 0xba6e4ec0,
|
||||
0x99265164, 0x1ee7230d, 0x50b2ad80, 0xeaee6801, 0x8db2a283,
|
||||
0xea8bf59e };
|
||||
|
@ -1,248 +0,0 @@
|
||||
/* -*- C -*- */
|
||||
|
||||
/*
|
||||
* stream_template.c : Generic framework for stream ciphers
|
||||
*
|
||||
* Distribute and use freely; there are no restrictions on further
|
||||
* dissemination and usage except those imposed by the laws of your
|
||||
* country of residence. This software is provided "as is" without
|
||||
* warranty of fitness for use or suitability for any purpose, express
|
||||
* or implied. Use at your own risk or not at all.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef _HAVE_STDC_HEADERS
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#include "Python.h"
|
||||
#include "modsupport.h"
|
||||
|
||||
#define _STR(x) #x
|
||||
#define _XSTR(x) _STR(x)
|
||||
#define _PASTE(x,y) x##y
|
||||
#define _PASTE2(x,y) _PASTE(x,y)
|
||||
#define _MODULE_NAME _PASTE2(init,MODULE_NAME)
|
||||
#define _MODULE_STRING _XSTR(MODULE_NAME)
|
||||
|
||||
/*
|
||||
*
|
||||
* Python interface
|
||||
*
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PyObject_HEAD
|
||||
stream_state st;
|
||||
} ALGobject;
|
||||
|
||||
staticforward PyTypeObject ALGtype;
|
||||
|
||||
#define is_ALGobject(v) ((v)->ob_type == &ALGtype)
|
||||
|
||||
static ALGobject *
|
||||
newALGobject(void)
|
||||
{
|
||||
ALGobject * new;
|
||||
new = PyObject_New(ALGobject, &ALGtype);
|
||||
return new;
|
||||
}
|
||||
|
||||
static void
|
||||
ALGdealloc(PyObject *ptr)
|
||||
{
|
||||
ALGobject *self = (ALGobject *)ptr;
|
||||
|
||||
/* Overwrite the contents of the object */
|
||||
memset((char*)&(self->st), 0, sizeof(stream_state));
|
||||
PyObject_Del(ptr);
|
||||
}
|
||||
|
||||
static char ALGnew__doc__[] =
|
||||
"Return a new " _MODULE_STRING " encryption object.";
|
||||
|
||||
static char *kwlist[] = {"key", NULL};
|
||||
|
||||
static ALGobject *
|
||||
ALGnew(PyObject *self, PyObject *args, PyObject *kwdict)
|
||||
{
|
||||
unsigned char *key;
|
||||
ALGobject * new;
|
||||
int keylen;
|
||||
|
||||
new = newALGobject();
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwdict, "s#", kwlist,
|
||||
&key, &keylen))
|
||||
{
|
||||
Py_DECREF(new);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (KEY_SIZE!=0 && keylen != KEY_SIZE)
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
_MODULE_STRING " key must be "
|
||||
"KEY_SIZE bytes long");
|
||||
return NULL;
|
||||
}
|
||||
if (KEY_SIZE== 0 && keylen == 0)
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
_MODULE_STRING " key cannot be "
|
||||
"the null string (0 bytes long)");
|
||||
return NULL;
|
||||
}
|
||||
stream_init(&(new->st), key, keylen);
|
||||
if (PyErr_Occurred())
|
||||
{
|
||||
Py_DECREF(new);
|
||||
return NULL;
|
||||
}
|
||||
return new;
|
||||
}
|
||||
|
||||
static char ALG_Encrypt__doc__[] =
|
||||
"Decrypt the provided string of binary data.";
|
||||
|
||||
static PyObject *
|
||||
ALG_Encrypt(ALGobject *self, PyObject *args)
|
||||
{
|
||||
unsigned char *buffer, *str;
|
||||
int len;
|
||||
PyObject *result;
|
||||
|
||||
if (!PyArg_Parse(args, "s#", &str, &len))
|
||||
return NULL;
|
||||
if (len == 0) /* Handle empty string */
|
||||
{
|
||||
return PyString_FromStringAndSize(NULL, 0);
|
||||
}
|
||||
buffer = malloc(len);
|
||||
if (buffer == NULL)
|
||||
{
|
||||
PyErr_SetString(PyExc_MemoryError, "No memory available in "
|
||||
_MODULE_STRING " encrypt");
|
||||
return NULL;
|
||||
}
|
||||
memcpy(buffer, str, len);
|
||||
stream_encrypt(&(self->st), buffer, len);
|
||||
result = PyString_FromStringAndSize(buffer, len);
|
||||
free(buffer);
|
||||
return (result);
|
||||
}
|
||||
|
||||
static char ALG_Decrypt__doc__[] =
|
||||
"decrypt(string): Decrypt the provided string of binary data.";
|
||||
|
||||
static PyObject *
|
||||
ALG_Decrypt(ALGobject *self, PyObject *args)
|
||||
{
|
||||
char *buffer, *str;
|
||||
int len;
|
||||
PyObject *result;
|
||||
|
||||
if (!PyArg_Parse(args, "s#", &str, &len))
|
||||
return NULL;
|
||||
if (len == 0) /* Handle empty string */
|
||||
{
|
||||
return PyString_FromStringAndSize(NULL, 0);
|
||||
}
|
||||
buffer = malloc(len);
|
||||
if (buffer == NULL)
|
||||
{
|
||||
PyErr_SetString(PyExc_MemoryError, "No memory available in "
|
||||
_MODULE_STRING " decrypt");
|
||||
return NULL;
|
||||
}
|
||||
memcpy(buffer, str, len);
|
||||
stream_decrypt(&(self->st), buffer, len);
|
||||
result = PyString_FromStringAndSize(buffer, len);
|
||||
free(buffer);
|
||||
return (result);
|
||||
}
|
||||
|
||||
/* ALGobject methods */
|
||||
|
||||
static PyMethodDef ALGmethods[] =
|
||||
{
|
||||
{"encrypt", (PyCFunction) ALG_Encrypt, 0, ALG_Encrypt__doc__},
|
||||
{"decrypt", (PyCFunction) ALG_Decrypt, 0, ALG_Decrypt__doc__},
|
||||
{NULL, NULL} /* sentinel */
|
||||
};
|
||||
|
||||
static PyObject *
|
||||
ALGgetattr(PyObject *self, char *name)
|
||||
{
|
||||
if (strcmp(name, "block_size") == 0)
|
||||
{
|
||||
return PyInt_FromLong(BLOCK_SIZE);
|
||||
}
|
||||
if (strcmp(name, "key_size") == 0)
|
||||
{
|
||||
return PyInt_FromLong(KEY_SIZE);
|
||||
}
|
||||
return Py_FindMethod(ALGmethods, self, name);
|
||||
}
|
||||
|
||||
|
||||
/* List of functions defined in the module */
|
||||
|
||||
static struct PyMethodDef modulemethods[] =
|
||||
{
|
||||
{"new", (PyCFunction) ALGnew,
|
||||
METH_VARARGS|METH_KEYWORDS, ALGnew__doc__},
|
||||
{NULL, NULL} /* sentinel */
|
||||
};
|
||||
|
||||
static PyTypeObject ALGtype =
|
||||
{
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0, /*ob_size*/
|
||||
_MODULE_STRING, /*tp_name*/
|
||||
sizeof(ALGobject), /*tp_size*/
|
||||
0, /*tp_itemsize*/
|
||||
/* methods */
|
||||
ALGdealloc, /*tp_dealloc*/
|
||||
0, /*tp_print*/
|
||||
ALGgetattr, /*tp_getattr*/
|
||||
0, /*tp_setattr*/
|
||||
0, /*tp_compare*/
|
||||
0, /*tp_repr*/
|
||||
0, /*tp_as_number*/
|
||||
};
|
||||
|
||||
/* Initialization function for the module */
|
||||
|
||||
#if PYTHON_API_VERSION < 1011
|
||||
#define PyModule_AddIntConstant(m,n,v) {PyObject *o=PyInt_FromLong(v); \
|
||||
if (o!=NULL) \
|
||||
{PyDict_SetItemString(PyModule_GetDict(m),n,o); Py_DECREF(o);}}
|
||||
#endif
|
||||
|
||||
void
|
||||
_MODULE_NAME (void)
|
||||
{
|
||||
PyObject *m, *d, *x;
|
||||
|
||||
ALGtype.ob_type = &PyType_Type;
|
||||
/* Create the module and add the functions */
|
||||
m = Py_InitModule("allmydata.Crypto.Cipher." _MODULE_STRING, modulemethods);
|
||||
|
||||
/* Add some symbolic constants to the module */
|
||||
d = PyModule_GetDict(m);
|
||||
x = PyString_FromString(_MODULE_STRING ".error");
|
||||
PyDict_SetItemString(d, "error", x);
|
||||
|
||||
PyModule_AddIntConstant(m, "block_size", BLOCK_SIZE);
|
||||
PyModule_AddIntConstant(m, "key_size", KEY_SIZE);
|
||||
|
||||
/* Check for errors */
|
||||
if (PyErr_Occurred())
|
||||
Py_FatalError("can't initialize module " _MODULE_STRING);
|
||||
}
|
@ -1,366 +0,0 @@
|
||||
/* -*- C -*- */
|
||||
/*
|
||||
* Uses Windows CryptoAPI CryptGenRandom to get random bytes.
|
||||
* The "new" method returns an object, whose "get_bytes" method
|
||||
* can be called repeatedly to get random bytes, seeded by the
|
||||
* OS. See the description in the comment at the end.
|
||||
*
|
||||
* If you have the Intel Security Driver header files (icsp4ms.h)
|
||||
* for their hardware random number generator in the 810 and 820 chipsets,
|
||||
* then define HAVE_INTEL_RNG.
|
||||
*
|
||||
* Distribute and use freely; there are no restrictions on further
|
||||
* dissemination and usage except those imposed by the laws of your
|
||||
* country of residence. This software is provided "as is" without
|
||||
* warranty of fitness for use or suitability for any purpose, express
|
||||
* or implied. Use at your own risk or not at all.
|
||||
*
|
||||
*/
|
||||
|
||||
/* Author: Mark Moraes */
|
||||
|
||||
#include "Python.h"
|
||||
|
||||
#ifdef MS_WIN32
|
||||
|
||||
#define _WIN32_WINNT 0x400
|
||||
#define WINSOCK
|
||||
|
||||
#include <windows.h>
|
||||
#include <wincrypt.h>
|
||||
|
||||
#ifdef HAVE_INTEL_RNG
|
||||
# include "icsp4ms.h"
|
||||
#else
|
||||
# define PROV_INTEL_SEC 22
|
||||
# define INTEL_DEF_PROV "Intel Hardware Cryptographic Service Provider"
|
||||
#endif
|
||||
|
||||
/* To-Do: store provider name and type for print/repr? */
|
||||
typedef struct
|
||||
{
|
||||
PyObject_HEAD
|
||||
HCRYPTPROV hcp;
|
||||
} WRobject;
|
||||
|
||||
staticforward PyTypeObject WRtype;
|
||||
|
||||
#define is_WRobject(v) ((v)->ob_type == &WRtype)
|
||||
|
||||
static void
|
||||
WRdealloc(PyObject *ptr)
|
||||
{
|
||||
WRobject *o = (WRobject *)ptr;
|
||||
|
||||
if (! is_WRobject(ptr)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"WinRandom trying to dealloc non-WinRandom object");
|
||||
return;
|
||||
}
|
||||
if (! CryptReleaseContext(o->hcp, 0)) {
|
||||
PyErr_Format(PyExc_SystemError,
|
||||
"CryptReleaseContext failed, error 0x%x",
|
||||
GetLastError());
|
||||
return;
|
||||
}
|
||||
/* Overwrite the contents of the object */
|
||||
o->hcp = 0;
|
||||
PyObject_Del(ptr);
|
||||
}
|
||||
|
||||
static char winrandom__doc__[] =
|
||||
"new([provider], [provtype]): Returns an object handle to Windows\n\
|
||||
CryptoAPI that can be used to access a cryptographically strong\n\
|
||||
pseudo-random generator that uses OS-gathered entropy.\n\
|
||||
Provider is a string that specifies the Cryptographic Service Provider\n\
|
||||
to use, default is the default OS CSP.\n\
|
||||
provtype is an integer specifying the provider type to use, default\n\
|
||||
is 1 (PROV_RSA_FULL)";
|
||||
|
||||
static char WR_get_bytes__doc__[] =
|
||||
"get_bytes(nbytes, [userdata]]): Returns nbytes of random data\n\
|
||||
from Windows CryptGenRandom.\n\
|
||||
userdata is a string with any additional entropic data that the\n\
|
||||
user wishes to provide.";
|
||||
|
||||
static WRobject *
|
||||
winrandom_new(PyObject *self, PyObject *args, PyObject *kwdict)
|
||||
{
|
||||
HCRYPTPROV hcp = 0;
|
||||
WRobject *res;
|
||||
char *provname = NULL;
|
||||
int provtype = PROV_RSA_FULL;
|
||||
static char *kwlist[] = { "provider", "provtype", NULL};
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwdict, "|si", kwlist,
|
||||
&provname, &provtype)) {
|
||||
return NULL;
|
||||
}
|
||||
if (! CryptAcquireContext(&hcp, NULL, (LPCTSTR) provname,
|
||||
(DWORD) provtype, 0)) {
|
||||
PyErr_Format(PyExc_SystemError,
|
||||
"CryptAcquireContext for provider \"%s\" type %i failed, error 0x%x",
|
||||
provname? provname : "(null)", provtype,
|
||||
GetLastError());
|
||||
return NULL;
|
||||
}
|
||||
res = PyObject_New(WRobject, &WRtype);
|
||||
res->hcp = hcp;
|
||||
return res;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
WR_get_bytes(WRobject *self, PyObject *args)
|
||||
{
|
||||
HCRYPTPROV hcp = 0;
|
||||
int n, nbytes, len = 0;
|
||||
PyObject *res;
|
||||
char *buf, *str = NULL;
|
||||
|
||||
if (! is_WRobject(self)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"WinRandom trying to get_bytes with non-WinRandom object");
|
||||
return NULL;
|
||||
}
|
||||
if (!PyArg_ParseTuple(args, "i|s#", &n, &str, &len)) {
|
||||
return NULL;
|
||||
}
|
||||
if (n <= 0) {
|
||||
PyErr_SetString(PyExc_ValueError, "nbytes must be positive number");
|
||||
return NULL;
|
||||
}
|
||||
/* Just in case char != BYTE, or userdata > desired result */
|
||||
nbytes = (((n > len) ? n : len) * sizeof(char)) / sizeof(BYTE) + 1;
|
||||
if ((buf = (char *) PyMem_Malloc(nbytes)) == NULL)
|
||||
return PyErr_NoMemory();
|
||||
if (len > 0)
|
||||
memcpy(buf, str, len);
|
||||
/*
|
||||
* if userdata > desired result, we end up getting
|
||||
* more bytes than we really needed to return. No
|
||||
* easy way to avoid that: we prefer that
|
||||
* CryptGenRandom does the distillation of userdata
|
||||
* down to entropy, rather than trying to do it
|
||||
* ourselves. Since the extra bytes presumably come
|
||||
* from an RC4 stream, they should be relatively
|
||||
* cheap.
|
||||
*/
|
||||
if (! CryptGenRandom(self->hcp, (DWORD) nbytes, (BYTE *) buf)) {
|
||||
PyErr_Format(PyExc_SystemError,
|
||||
"CryptGenRandom failed, error 0x%x",
|
||||
GetLastError());
|
||||
PyMem_Free(buf);
|
||||
return NULL;
|
||||
}
|
||||
res = PyString_FromStringAndSize(buf, n);
|
||||
PyMem_Free(buf);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* WinRandom object methods */
|
||||
|
||||
static PyMethodDef WRmethods[] =
|
||||
{
|
||||
{"get_bytes", (PyCFunction) WR_get_bytes, METH_VARARGS,
|
||||
WR_get_bytes__doc__},
|
||||
{NULL, NULL} /* sentinel */
|
||||
};
|
||||
|
||||
/* winrandom module methods */
|
||||
|
||||
static PyMethodDef WR_mod_methods[] = {
|
||||
{"new", (PyCFunction) winrandom_new, METH_VARARGS|METH_KEYWORDS,
|
||||
winrandom__doc__},
|
||||
{NULL, NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
|
||||
static PyObject *
|
||||
WRgetattr(PyObject *s, char *name)
|
||||
{
|
||||
WRobject *self = (WRobject*)s;
|
||||
if (! is_WRobject(self)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"WinRandom trying to getattr with non-WinRandom object");
|
||||
return NULL;
|
||||
}
|
||||
if (strcmp(name, "hcp") == 0)
|
||||
return PyInt_FromLong((long) self->hcp);
|
||||
return Py_FindMethod(WRmethods, (PyObject *) self, name);
|
||||
}
|
||||
|
||||
static PyTypeObject WRtype =
|
||||
{
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0, /*ob_size*/
|
||||
"winrandom.WinRandom", /*tp_name*/
|
||||
sizeof(WRobject), /*tp_size*/
|
||||
0, /*tp_itemsize*/
|
||||
/* methods */
|
||||
WRdealloc, /*tp_dealloc*/
|
||||
0, /*tp_print*/
|
||||
WRgetattr, /*tp_getattr*/
|
||||
};
|
||||
|
||||
void
|
||||
initwinrandom()
|
||||
{
|
||||
PyObject *m;
|
||||
WRtype.ob_type = &PyType_Type;
|
||||
m = Py_InitModule("winrandom", WR_mod_methods);
|
||||
|
||||
/* define Windows CSP Provider Types */
|
||||
#ifdef PROV_RSA_FULL
|
||||
PyModule_AddIntConstant(m, "PROV_RSA_FULL", PROV_RSA_FULL);
|
||||
#endif
|
||||
#ifdef PROV_RSA_SIG
|
||||
PyModule_AddIntConstant(m, "PROV_RSA_SIG", PROV_RSA_SIG);
|
||||
#endif
|
||||
#ifdef PROV_DSS
|
||||
PyModule_AddIntConstant(m, "PROV_DSS", PROV_DSS);
|
||||
#endif
|
||||
#ifdef PROV_FORTEZZA
|
||||
PyModule_AddIntConstant(m, "PROV_FORTEZZA", PROV_FORTEZZA);
|
||||
#endif
|
||||
#ifdef PROV_MS_EXCHANGE
|
||||
PyModule_AddIntConstant(m, "PROV_MS_EXCHANGE", PROV_MS_EXCHANGE);
|
||||
#endif
|
||||
#ifdef PROV_SSL
|
||||
PyModule_AddIntConstant(m, "PROV_SSL", PROV_SSL);
|
||||
#endif
|
||||
#ifdef PROV_RSA_SCHANNEL
|
||||
PyModule_AddIntConstant(m, "PROV_RSA_SCHANNEL", PROV_RSA_SCHANNEL);
|
||||
#endif
|
||||
#ifdef PROV_DSS_DH
|
||||
PyModule_AddIntConstant(m, "PROV_DSS_DH", PROV_DSS_DH);
|
||||
#endif
|
||||
#ifdef PROV_EC_ECDSA_SIG
|
||||
PyModule_AddIntConstant(m, "PROV_EC_ECDSA_SIG", PROV_EC_ECDSA_SIG);
|
||||
#endif
|
||||
#ifdef PROV_EC_ECNRA_SIG
|
||||
PyModule_AddIntConstant(m, "PROV_EC_ECNRA_SIG", PROV_EC_ECNRA_SIG);
|
||||
#endif
|
||||
#ifdef PROV_EC_ECDSA_FULL
|
||||
PyModule_AddIntConstant(m, "PROV_EC_ECDSA_FULL", PROV_EC_ECDSA_FULL);
|
||||
#endif
|
||||
#ifdef PROV_EC_ECNRA_FULL
|
||||
PyModule_AddIntConstant(m, "PROV_EC_ECNRA_FULL", PROV_EC_ECNRA_FULL);
|
||||
#endif
|
||||
#ifdef PROV_SPYRUS_LYNKS
|
||||
PyModule_AddIntConstant(m, "PROV_SPYRUS_LYNKS", PROV_SPYRUS_LYNKS);
|
||||
#endif
|
||||
#ifdef PROV_INTEL_SEC
|
||||
PyModule_AddIntConstant(m, "PROV_INTEL_SEC", PROV_INTEL_SEC);
|
||||
#endif
|
||||
|
||||
/* Define Windows CSP Provider Names */
|
||||
#ifdef MS_DEF_PROV
|
||||
PyModule_AddStringConstant(m, "MS_DEF_PROV", MS_DEF_PROV);
|
||||
#endif
|
||||
#ifdef MS_ENHANCED_PROV
|
||||
PyModule_AddStringConstant(m, "MS_ENHANCED_PROV", MS_ENHANCED_PROV);
|
||||
#endif
|
||||
#ifdef MS_DEF_RSA_SIG_PROV
|
||||
PyModule_AddStringConstant(m, "MS_DEF_RSA_SIG_PROV",
|
||||
MS_DEF_RSA_SIG_PROV);
|
||||
#endif
|
||||
#ifdef MS_DEF_RSA_SCHANNEL_PROV
|
||||
PyModule_AddStringConstant(m, "MS_DEF_RSA_SCHANNEL_PROV",
|
||||
MS_DEF_RSA_SCHANNEL_PROV);
|
||||
#endif
|
||||
#ifdef MS_ENHANCED_RSA_SCHANNEL_PROV
|
||||
PyModule_AddStringConstant(m, "MS_ENHANCED_RSA_SCHANNEL_PROV",
|
||||
MS_ENHANCED_RSA_SCHANNEL_PROV);
|
||||
#endif
|
||||
#ifdef MS_DEF_DSS_PROV
|
||||
PyModule_AddStringConstant(m, "MS_DEF_DSS_PROV", MS_DEF_DSS_PROV);
|
||||
#endif
|
||||
#ifdef MS_DEF_DSS_DH_PROV
|
||||
PyModule_AddStringConstant(m, "MS_DEF_DSS_DH_PROV",
|
||||
MS_DEF_DSS_DH_PROV);
|
||||
#endif
|
||||
#ifdef INTEL_DEF_PROV
|
||||
PyModule_AddStringConstant(m, "INTEL_DEF_PROV", INTEL_DEF_PROV);
|
||||
#endif
|
||||
|
||||
if (PyErr_Occurred())
|
||||
Py_FatalError("can't initialize module winrandom");
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
CryptGenRandom usage is described in
|
||||
http://msdn.microsoft.com/library/en-us/security/security/cryptgenrandom.asp
|
||||
and many associated pages on Windows Cryptographic Service
|
||||
Providers, which say:
|
||||
|
||||
With Microsoft CSPs, CryptGenRandom uses the same
|
||||
random number generator used by other security
|
||||
components. This allows numerous processes to
|
||||
contribute to a system-wide seed. CryptoAPI stores
|
||||
an intermediate random seed with every user. To form
|
||||
the seed for the random number generator, a calling
|
||||
application supplies bits it might havefor instance,
|
||||
mouse or keyboard timing inputthat are then added to
|
||||
both the stored seed and various system data and
|
||||
user data such as the process ID and thread ID, the
|
||||
system clock, the system time, the system counter,
|
||||
memory status, free disk clusters, the hashed user
|
||||
environment block. This result is SHA-1 hashed, and
|
||||
the output is used to seed an RC4 stream, which is
|
||||
then used as the random stream and used to update
|
||||
the stored seed.
|
||||
|
||||
The only other detailed description I've found of the
|
||||
sources of randomness for CryptGenRandom is this excerpt
|
||||
from a posting
|
||||
http://www.der-keiler.de/Newsgroups/comp.security.ssh/2002-06/0169.html
|
||||
|
||||
From: Jon McClelland (dowot69@hotmail.com)
|
||||
Date: 06/12/02
|
||||
...
|
||||
|
||||
Windows, call a function such as CryptGenRandom, which has two of
|
||||
the properties of a good random number generator, unpredictability and
|
||||
even value distribution. This function, declared in Wincrypt.h, is
|
||||
available on just about every Windows platform, including Windows 95
|
||||
with Internet Explorer 3.02 or later, Windows 98, Windows Me, Windows
|
||||
CE v3, Windows NT 4, Windows 2000, and Windows XP.
|
||||
|
||||
CryptGenRandom gets its randomness, also known as entropy, from many
|
||||
sources in Windows 2000, including the following:
|
||||
The current process ID (GetCurrentProcessID).
|
||||
The current thread ID (GetCurrentThreadID).
|
||||
The ticks since boot (GetTickCount).
|
||||
The current time (GetLocalTime).
|
||||
Various high-precision performance counters (QueryPerformanceCounter).
|
||||
A Message Digest 4 (MD4) hash of the user's environment block, which
|
||||
includes username, computer name, and search path.
|
||||
|
||||
High-precision internal CPU counters, such as RDTSC, RDMSR, RDPMC (x86
|
||||
only-more information about these counters is at
|
||||
developer.intel.com/software/idap/resources/technical_collateral/pentiumii/RDTSCPM1.HTM
|
||||
<http://developer.intel.com>).
|
||||
|
||||
Low-level system information, such as idle time, kernel time,
|
||||
interrupt times, commit limit, page read count, cache read count,
|
||||
nonpaged pool allocations, alignment fixup count, operating system
|
||||
lookaside information.
|
||||
|
||||
Such information is added to a buffer, which is hashed using MD4 and
|
||||
used as the key to modify a buffer, using RC4, provided by the user.
|
||||
(Refer to the CryptGenRandom documentation in the Platform SDK for
|
||||
more information about the user-provided buffer.) Hence, if the user
|
||||
provides additional data in the buffer, this is used as an element in
|
||||
the witches brew to generate the random data. The result is a
|
||||
cryptographically random number generator.
|
||||
Also, note that if you plan to sell your software to the United States
|
||||
federal government, you'll need to use FIPS 140-1-approved algorithms.
|
||||
The default versions of CryptGenRandom in Microsoft Windows CE v3,
|
||||
Windows 95, Windows 98, Windows Me, Windows 2000, and Windows XP are
|
||||
FIPS-approved. Obviously FIPS-140 compliance is necessary but not
|
||||
sufficient to provide a properly secure source of random data.
|
||||
|
||||
*/
|
||||
|
||||
#endif /* MS_WIN32 */
|
@ -1,40 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
#
|
||||
# Test script for the Python Cryptography Toolkit.
|
||||
#
|
||||
|
||||
__revision__ = "$Id: test.py,v 1.7 2002/07/11 14:31:19 akuchling Exp $"
|
||||
|
||||
import os, sys
|
||||
|
||||
|
||||
# Add the build directory to the front of sys.path
|
||||
from distutils.util import get_platform
|
||||
s = "build/lib.%s-%.3s" % (get_platform(), sys.version)
|
||||
s = os.path.join(os.getcwd(), s)
|
||||
sys.path.insert(0, s)
|
||||
s = os.path.join(os.getcwd(), 'test')
|
||||
sys.path.insert(0, s)
|
||||
|
||||
from allmydata.Crypto.Util import test
|
||||
|
||||
args = sys.argv[1:]
|
||||
quiet = "--quiet" in args
|
||||
if quiet: args.remove('--quiet')
|
||||
|
||||
if not quiet:
|
||||
print '\nStream Ciphers:'
|
||||
print '==============='
|
||||
|
||||
if args: test.TestStreamModules(args, verbose= not quiet)
|
||||
else: test.TestStreamModules(verbose= not quiet)
|
||||
|
||||
if not quiet:
|
||||
print '\nBlock Ciphers:'
|
||||
print '=============='
|
||||
|
||||
if args: test.TestBlockModules(args, verbose= not quiet)
|
||||
else: test.TestBlockModules(verbose= not quiet)
|
||||
|
||||
|
@ -1,26 +0,0 @@
|
||||
#
|
||||
# Test script for Crypto.XXX
|
||||
#
|
||||
|
||||
__revision__ = "$Id: template,v 1.1 2002/05/17 13:31:48 akuchling Exp $"
|
||||
|
||||
from sancho.unittest import TestScenario, parse_args, run_scenarios
|
||||
|
||||
tested_modules = [ "Crypto.XXX" ]
|
||||
|
||||
class XXXTest (TestScenario):
|
||||
|
||||
def setup (self):
|
||||
pass
|
||||
|
||||
def shutdown (self):
|
||||
pass
|
||||
|
||||
def check_ (self):
|
||||
""
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
(scenarios, options) = parse_args()
|
||||
run_scenarios(scenarios, options)
|
@ -1,58 +0,0 @@
|
||||
#
|
||||
# Test script for Crypto.XXX
|
||||
#
|
||||
|
||||
__revision__ = "$Id: test_chaffing.py,v 1.2 2003/02/28 15:23:59 akuchling Exp $"
|
||||
|
||||
from sancho.unittest import TestScenario, parse_args, run_scenarios
|
||||
from allmydata.Crypto.Protocol import Chaffing
|
||||
|
||||
tested_modules = [ "Crypto.Protocol.Chaffing" ]
|
||||
|
||||
text = """\
|
||||
When in the Course of human events, it becomes necessary for one people to
|
||||
dissolve the political bands which have connected them with another, and to
|
||||
assume among the powers of the earth, the separate and equal station to which
|
||||
the Laws of Nature and of Nature's God entitle them, a decent respect to the
|
||||
opinions of mankind requires that they should declare the causes which impel
|
||||
them to the separation.
|
||||
|
||||
We hold these truths to be self-evident, that all men are created equal, that
|
||||
they are endowed by their Creator with certain unalienable Rights, that among
|
||||
these are Life, Liberty, and the pursuit of Happiness. That to secure these
|
||||
rights, Governments are instituted among Men, deriving their just powers from
|
||||
the consent of the governed. That whenever any Form of Government becomes
|
||||
destructive of these ends, it is the Right of the People to alter or to
|
||||
abolish it, and to institute new Government, laying its foundation on such
|
||||
principles and organizing its powers in such form, as to them shall seem most
|
||||
likely to effect their Safety and Happiness.
|
||||
"""
|
||||
|
||||
class ChaffingTest (TestScenario):
|
||||
|
||||
def setup (self):
|
||||
pass
|
||||
|
||||
def shutdown (self):
|
||||
pass
|
||||
|
||||
def check_chaffing (self):
|
||||
"Simple tests of chaffing and winnowing"
|
||||
self.test_stmt('Chaffing.Chaff()')
|
||||
self.test_stmt('Chaffing.Chaff(0.5, 1)')
|
||||
self.test_exc('Chaffing.Chaff(factor=-1)', ValueError)
|
||||
self.test_exc('Chaffing.Chaff(blocksper=-1)', ValueError)
|
||||
|
||||
data = [(1, 'data1', 'data1'), (2, 'data2', 'data2')]
|
||||
c = Chaffing.Chaff(1.0, 1)
|
||||
self.test_stmt('c.chaff(data)')
|
||||
chaff = c.chaff(data)
|
||||
self.test_val('len(chaff)', 4)
|
||||
|
||||
c = Chaffing.Chaff(0.0, 1)
|
||||
chaff = c.chaff(data)
|
||||
self.test_val('len(chaff)', 2)
|
||||
|
||||
if __name__ == "__main__":
|
||||
(scenarios, options) = parse_args()
|
||||
run_scenarios(scenarios, options)
|
@ -1,94 +0,0 @@
|
||||
#
|
||||
# Test script for Crypto.Util.randpool.
|
||||
#
|
||||
|
||||
__revision__ = "$Id: test_hashes.py,v 1.4 2004/08/13 22:23:12 akuchling Exp $"
|
||||
|
||||
import time, string, binascii
|
||||
from sancho.unittest import TestScenario, parse_args, run_scenarios
|
||||
|
||||
from allmydata.Crypto.Hash import *
|
||||
import testdata
|
||||
|
||||
tested_modules = [ "Crypto.Hash.MD2", "Crypto.Hash.MD4", "Crypto.Hash.MD5",
|
||||
"Crypto.Hash.RIPEMD", "Crypto.Hash.SHA", "Crypto.Hash.SHA256"]
|
||||
|
||||
class HashTest (TestScenario):
|
||||
|
||||
def setup (self):
|
||||
teststr='1' # Build 128K of test data
|
||||
for i in xrange(0, 17):
|
||||
teststr=teststr+teststr
|
||||
self.str_128k = teststr
|
||||
|
||||
def shutdown (self):
|
||||
del self.str_128k
|
||||
|
||||
def compare(self, hash_mod, strg, hex_result):
|
||||
result = binascii.a2b_hex(hex_result)
|
||||
obj = hash_mod.new(strg)
|
||||
s1 = obj.digest()
|
||||
|
||||
# Check that the right hash result is produced
|
||||
self.test_val('s1', result)
|
||||
|
||||
# Check that .hexdigest() produces the same output
|
||||
self.test_val('obj.hexdigest()', hex_result)
|
||||
|
||||
# Test second hashing, and copying of a hashing object
|
||||
self.test_val('obj.digest()', result)
|
||||
self.test_val('obj.copy().digest()', result)
|
||||
|
||||
|
||||
def run_test_suite (self, hash_mod, test_vectors):
|
||||
for text, digest in test_vectors:
|
||||
self.compare(hash_mod, text, digest)
|
||||
|
||||
def benchmark (self, hash_mod):
|
||||
obj = hash_mod.new()
|
||||
start=time.time()
|
||||
s=obj.update(self.str_128k)
|
||||
end=time.time()
|
||||
delta = end-start
|
||||
print hash_mod.__name__, ':',
|
||||
if delta == 0:
|
||||
print 'Unable to measure time -- elapsed time too small'
|
||||
else:
|
||||
print '%.2f K/sec' % (128/(end-start))
|
||||
|
||||
def check_md2 (self):
|
||||
"MD2 module"
|
||||
self.run_test_suite(MD2, testdata.md2)
|
||||
self.benchmark(MD2)
|
||||
|
||||
def check_md4 (self):
|
||||
"MD4 module"
|
||||
self.run_test_suite(MD4, testdata.md4)
|
||||
self.benchmark(MD4)
|
||||
|
||||
def check_md5 (self):
|
||||
"MD5 module"
|
||||
self.run_test_suite(MD5, testdata.md5)
|
||||
self.benchmark(MD5)
|
||||
|
||||
def check_ripemd (self):
|
||||
"RIPEMD module"
|
||||
self.run_test_suite(RIPEMD, testdata.ripemd)
|
||||
self.benchmark(RIPEMD)
|
||||
|
||||
def check_sha (self):
|
||||
"SHA module"
|
||||
self.run_test_suite(SHA, testdata.sha)
|
||||
self.benchmark(SHA)
|
||||
|
||||
def check_sha256 (self):
|
||||
"SHA256 module"
|
||||
self.run_test_suite(SHA256,testdata.sha256)
|
||||
self.benchmark(SHA256)
|
||||
|
||||
# class HashTest
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
(scenarios, options) = parse_args()
|
||||
run_scenarios(scenarios, options)
|
@ -1,85 +0,0 @@
|
||||
#
|
||||
# Test script for Crypto.Util.number.
|
||||
#
|
||||
|
||||
__revision__ = "$Id: test_number.py,v 1.4 2003/04/04 18:21:35 akuchling Exp $"
|
||||
|
||||
from sancho.unittest import TestScenario, parse_args, run_scenarios
|
||||
from allmydata.Crypto.Util import number
|
||||
|
||||
tested_modules = [ "Crypto.Util.number" ]
|
||||
|
||||
class NumberTest (TestScenario):
|
||||
|
||||
def setup (self):
|
||||
pass
|
||||
|
||||
def shutdown (self):
|
||||
pass
|
||||
|
||||
def check_getRandomNumber (self):
|
||||
"Check generation of N-bit random numbers"
|
||||
def f(N):
|
||||
return '\xff' * N
|
||||
|
||||
self.test_val('number.getRandomNumber(1, f)', 1)
|
||||
self.test_val('number.getRandomNumber(4, f)', 15)
|
||||
self.test_val('number.getRandomNumber(8, f)', 255)
|
||||
self.test_val('number.getRandomNumber(12, f)', 4095)
|
||||
self.test_val('number.getRandomNumber(16, f)', 65535)
|
||||
|
||||
def check_GCD (self):
|
||||
"Check GCD computation"
|
||||
self.test_val('number.GCD(1, 5)', 1)
|
||||
self.test_val('number.GCD(2, 6)', 2)
|
||||
self.test_val('number.GCD(16, 12)', 4)
|
||||
|
||||
def check_inverse (self):
|
||||
"Check computation of inverses"
|
||||
self.test_val('number.inverse(9, 10)', 9)
|
||||
self.test_val('number.inverse(1, 2)', 1)
|
||||
self.test_val('number.inverse(529, 10502)', 3097)
|
||||
|
||||
def check_getPrime (self):
|
||||
"Check generation of primes"
|
||||
def f(n):
|
||||
return '\xff' * n
|
||||
self.test_val('number.getPrime(1, f)', 3)
|
||||
self.test_val('number.getPrime(2, f)', 3)
|
||||
self.test_val('number.getPrime(8, f)', 257)
|
||||
self.test_val('number.getPrime(75, f)', 37778931862957161709601L)
|
||||
|
||||
def check_isPrime (self):
|
||||
"Check verification of primes"
|
||||
self.test_bool('number.isPrime(1)', want_true=0)
|
||||
self.test_bool('number.isPrime(2)')
|
||||
self.test_bool('number.isPrime(3)')
|
||||
self.test_bool('number.isPrime(4)', want_true=0)
|
||||
self.test_bool('number.isPrime(37778931862957161709601L)')
|
||||
self.test_bool('number.isPrime(37778931862957161709603L)',
|
||||
want_true=0)
|
||||
|
||||
def check_longbytes (self):
|
||||
"Check conversion between bytes and integers"
|
||||
self.test_val('number.long_to_bytes(1)', '\x01')
|
||||
self.test_val('number.long_to_bytes(1, 2)', '\x00\x01')
|
||||
self.test_val('number.long_to_bytes(511)', '\x01\xff')
|
||||
|
||||
self.test_val('number.bytes_to_long("\x01")', 1)
|
||||
self.test_val('number.bytes_to_long("\xff\x01")', 0xff01)
|
||||
self.test_val('number.bytes_to_long("\x12\x34\x01")', 0x123401)
|
||||
|
||||
def check_size (self):
|
||||
"Check measurement of number sizes"
|
||||
self.test_val('number.size(1)', 1)
|
||||
self.test_val('number.size(15)', 4)
|
||||
self.test_val('number.size(255)', 8)
|
||||
self.test_val('number.size(256)', 9)
|
||||
|
||||
|
||||
# class NumberTest
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
(scenarios, options) = parse_args()
|
||||
run_scenarios(scenarios, options)
|
@ -1,122 +0,0 @@
|
||||
#
|
||||
# Test script for Crypto.Util.PublicKey.
|
||||
#
|
||||
|
||||
__revision__ = "$Id: test_publickey.py,v 1.7 2003/04/04 19:38:28 akuchling Exp $"
|
||||
|
||||
import sys, cPickle
|
||||
from sancho.unittest import TestScenario, parse_args, run_scenarios
|
||||
from allmydata.Crypto.PublicKey import *
|
||||
from allmydata.Crypto.Util.randpool import RandomPool
|
||||
from allmydata.Crypto.Util import number
|
||||
|
||||
tested_modules = [ "Crypto.PublicKey.RSA", "Crypto.PublicKey.DSA",
|
||||
"Crypto.PublicKey.ElGamal", "Crypto.PublicKey.qNEW"]
|
||||
|
||||
class PublicKeyTest (TestScenario):
|
||||
|
||||
def setup (self):
|
||||
# Set up a random pool; we won't bother to actually fill it with
|
||||
# entropy from the keyboard
|
||||
self.pool = RandomPool(384)
|
||||
self.pool.stir()
|
||||
|
||||
def shutdown (self):
|
||||
del self.pool
|
||||
|
||||
def testkey (self, key, randfunc, verbose=0):
|
||||
plaintext="Hello"
|
||||
# Generate maximum-size plaintext
|
||||
maxplain = (key.size() // 8) * '\377'
|
||||
|
||||
if key.can_encrypt():
|
||||
if verbose: print ' Encryption/decryption test'
|
||||
K=number.getPrime(10, randfunc)
|
||||
ciphertext=key.encrypt(plaintext, K)
|
||||
self.test_val('key.decrypt(ciphertext)', plaintext)
|
||||
ciphertext=key.encrypt(maxplain, K)
|
||||
self.test_val('key.decrypt(ciphertext)', maxplain)
|
||||
|
||||
if key.can_sign():
|
||||
if verbose: print ' Signature test'
|
||||
K=number.getPrime(30, randfunc)
|
||||
signature=key.sign(plaintext, K)
|
||||
self.test_bool('key.verify(plaintext, signature)')
|
||||
self.test_bool('key.verify(plaintext[:-1], signature)',
|
||||
want_true=0)
|
||||
|
||||
# Change a single bit in the plaintext
|
||||
badtext=plaintext[:-3]+chr( 1 ^ ord(plaintext[-3]) )+plaintext[-3:]
|
||||
self.test_bool('key.verify(badtext, signature)', want_true=0)
|
||||
|
||||
if verbose: print ' Removing private key data'
|
||||
pubonly=key.publickey()
|
||||
self.test_bool('pubonly.verify(plaintext, signature)')
|
||||
|
||||
# Test blinding
|
||||
if key.can_blind():
|
||||
if verbose: print ' Blinding test'
|
||||
K=number.getPrime(30, randfunc)
|
||||
B="garbage"
|
||||
blindedtext=key.blind(plaintext, B)
|
||||
signature=key.sign(blindedtext, K)
|
||||
unblindedsignature=(key.unblind(signature[0], B),)
|
||||
self.test_bool('key.verify(plaintext, unblindedsignature)')
|
||||
self.test_val('key.sign(plaintext, K)', unblindedsignature)
|
||||
|
||||
# Change a single bit in the blinding factor
|
||||
badB=B[:-3]+chr( 1 ^ ord(B[-3]) )+B[-3:]
|
||||
badunblindedsignature=(key.unblind(signature[0], badB),)
|
||||
self.test_false('key.verify(badtext, badunblindedsignature)')
|
||||
|
||||
badblindedtext=key.blind(plaintext, badB)
|
||||
badsignature=key.sign(blindedtext, K)
|
||||
badunblindedsignature2=(key.unblind(signature[0], B),)
|
||||
self.test_false('key.verify(badtext, badunblindedsignature2)')
|
||||
|
||||
|
||||
def exercise (self, randfunc, pk_mod, verbose=0):
|
||||
N=256 # Key size, measured in bits
|
||||
|
||||
key=pk_mod.generate(N, randfunc)
|
||||
|
||||
if verbose:
|
||||
print ' Key data:'
|
||||
for field in key.keydata:
|
||||
print " ", field, ':', hex(getattr(key,field))
|
||||
|
||||
if verbose: print " Testing newly generated key"
|
||||
self.testkey(key, randfunc, verbose)
|
||||
if verbose: print " Testing pickled/unpickled key"
|
||||
import pickle
|
||||
s = pickle.dumps(key) ; key2 = pickle.loads(s)
|
||||
self.testkey(key2, randfunc, verbose)
|
||||
|
||||
if verbose: print " Testing cPickled key"
|
||||
s = cPickle.dumps(key) ; key2 = cPickle.loads(s)
|
||||
self.testkey(key2, randfunc, verbose)
|
||||
if verbose: print
|
||||
|
||||
|
||||
def check_rsa(self):
|
||||
"Check RSA algorithm"
|
||||
self.exercise(self.pool.get_bytes, RSA)
|
||||
|
||||
def check_dsa(self):
|
||||
"Check DSA algorithm"
|
||||
self.exercise(self.pool.get_bytes, DSA)
|
||||
|
||||
def check_elgamal(self):
|
||||
"Check ElGamal algorithm"
|
||||
self.exercise(self.pool.get_bytes, ElGamal)
|
||||
|
||||
def check_qnew(self):
|
||||
"Check qNEW algorithm"
|
||||
self.exercise(self.pool.get_bytes, qNEW)
|
||||
|
||||
# class PublicKeyTest
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
(scenarios, options) = parse_args()
|
||||
run_scenarios(scenarios, options)
|
@ -1,48 +0,0 @@
|
||||
#
|
||||
# Test script for Crypto.Util.randpool.
|
||||
#
|
||||
|
||||
__revision__ = "$Id: test_randpool.py,v 1.3 2003/02/28 15:24:01 akuchling Exp $"
|
||||
|
||||
from sancho.unittest import TestScenario, parse_args, run_scenarios
|
||||
from allmydata.Crypto.Hash import SHA
|
||||
from allmydata.Crypto.Util import randpool
|
||||
|
||||
tested_modules = [ "Crypto.Util.randpool" ]
|
||||
|
||||
class RandomPoolTest (TestScenario):
|
||||
|
||||
def setup (self):
|
||||
self.pool = randpool.RandomPool(160, hash=SHA)
|
||||
|
||||
def shutdown (self):
|
||||
del self.pool
|
||||
|
||||
def check_init (self):
|
||||
"Check initial state"
|
||||
self.test_val('self.pool.entropy', self.pool.bits)
|
||||
|
||||
def check_get_bytes (self):
|
||||
"Check retrieving of bytes from the pool"
|
||||
start_entropy = self.pool.entropy
|
||||
self.test_bool('self.pool.entropy > 0')
|
||||
|
||||
# Draw out half of the pool's entropy
|
||||
size = self.pool.entropy / 8 / 2
|
||||
self.test_stmt('self.pool.get_bytes(size)')
|
||||
self.test_val('self.pool.entropy', start_entropy - size*8)
|
||||
|
||||
# Draw out the rest of the pool's entropy
|
||||
self.test_stmt('self.pool.get_bytes(size)')
|
||||
self.test_val('self.pool.entropy', 0)
|
||||
|
||||
# Remove yet more data; entropy stays at zero
|
||||
self.test_stmt('self.pool.get_bytes(size)')
|
||||
self.test_val('self.pool.entropy', 0)
|
||||
|
||||
# class RandomPoolTest
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
(scenarios, options) = parse_args()
|
||||
run_scenarios(scenarios, options)
|
@ -1,45 +0,0 @@
|
||||
#
|
||||
# Test script for Crypto.Util.randpool.
|
||||
#
|
||||
|
||||
__revision__ = "$Id: test_rfc1751.py,v 1.3 2003/02/28 15:24:01 akuchling Exp $"
|
||||
|
||||
import binascii
|
||||
from sancho.unittest import TestScenario, parse_args, run_scenarios
|
||||
from allmydata.Crypto.Util import RFC1751
|
||||
|
||||
tested_modules = [ "Crypto.Util.RFC1751" ]
|
||||
|
||||
test_data = [('EB33F77EE73D4053', 'TIDE ITCH SLOW REIN RULE MOT'),
|
||||
('CCAC2AED591056BE4F90FD441C534766',
|
||||
'RASH BUSH MILK LOOK BAD BRIM AVID GAFF BAIT ROT POD LOVE'),
|
||||
('EFF81F9BFBC65350920CDD7416DE8009',
|
||||
'TROD MUTE TAIL WARM CHAR KONG HAAG CITY BORE O TEAL AWL')
|
||||
]
|
||||
|
||||
class RFC1751Test (TestScenario):
|
||||
|
||||
def setup (self):
|
||||
pass
|
||||
|
||||
def shutdown (self):
|
||||
pass
|
||||
|
||||
def check_k2e (self):
|
||||
"Check converting keys to English"
|
||||
for key, words in test_data:
|
||||
key=binascii.a2b_hex(key)
|
||||
self.test_val('RFC1751.key_to_english(key)', words)
|
||||
|
||||
def check_e2k (self):
|
||||
"Check converting English strings to keys"
|
||||
for key, words in test_data:
|
||||
key=binascii.a2b_hex(key)
|
||||
self.test_val('RFC1751.english_to_key(words)', key)
|
||||
|
||||
# class RFC1751Test
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
(scenarios, options) = parse_args()
|
||||
run_scenarios(scenarios, options)
|
@ -1,667 +0,0 @@
|
||||
#
|
||||
# testdata.py : Test data for the various algorithms
|
||||
#
|
||||
# Part of the Python Cryptography Toolkit
|
||||
#
|
||||
# Distribute and use freely; there are no restrictions on further
|
||||
# dissemination and usage except those imposed by the laws of your
|
||||
# country of residence. This software is provided "as is" without
|
||||
# warranty of fitness for use or suitability for any purpose, express
|
||||
# or implied. Use at your own risk or not at all.
|
||||
#
|
||||
|
||||
# Data for encryption algorithms is saved as (key, plaintext,
|
||||
# ciphertext) tuples. Hashing algorithm test data is simply
|
||||
# (text, hashvalue) pairs.
|
||||
|
||||
# MD2 validation data
|
||||
|
||||
md2= [
|
||||
("", "8350e5a3e24c153df2275c9f80692773"),
|
||||
("a", "32ec01ec4a6dac72c0ab96fb34c0b5d1"),
|
||||
("abc", "da853b0d3f88d99b30283a69e6ded6bb"),
|
||||
("message digest", "ab4f496bfb2a530b219ff33031fe06b0"),
|
||||
("abcdefghijklmnopqrstuvwxyz", "4e8ddff3650292ab5a4108c3aa47940b"),
|
||||
("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
|
||||
"da33def2a42df13975352846c30338cd"),
|
||||
("12345678901234567890123456789012345678901234567890123456789012345678901234567890",
|
||||
"d5976f79d83d3a0dc9806c3c66f3efd8")
|
||||
]
|
||||
|
||||
# MD4 validation data
|
||||
|
||||
md4= [
|
||||
('', "31d6cfe0d16ae931b73c59d7e0c089c0"),
|
||||
("a", "bde52cb31de33e46245e05fbdbd6fb24"),
|
||||
("abc", "a448017aaf21d8525fc10ae87aa6729d"),
|
||||
("message digest", "d9130a8164549fe818874806e1c7014b"),
|
||||
("abcdefghijklmnopqrstuvwxyz", "d79e1c308aa5bbcdeea8ed63df412da9"),
|
||||
("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
|
||||
"043f8582f241db351ce627e153e7f0e4"),
|
||||
("12345678901234567890123456789012345678901234567890123456789012345678901234567890",
|
||||
"e33b4ddc9c38f2199c3e7b164fcc0536"),
|
||||
]
|
||||
|
||||
# MD5 validation data
|
||||
|
||||
md5= [
|
||||
('', "d41d8cd98f00b204e9800998ecf8427e"),
|
||||
('a', "0cc175b9c0f1b6a831c399e269772661"),
|
||||
('abc', "900150983cd24fb0d6963f7d28e17f72"),
|
||||
('message digest', "f96b697d7cb7938d525a2f31aaf161d0"),
|
||||
('abcdefghijklmnopqrstuvwxyz', "c3fcd3d76192e4007dfb496cca67e13b"),
|
||||
('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',
|
||||
"d174ab98d277d9f5a5611c2c9f419d9f"),
|
||||
('12345678901234567890123456789012345678901234567890123456789'
|
||||
'012345678901234567890', "57edf4a22be3c955ac49da2e2107b67a")
|
||||
]
|
||||
|
||||
# Test data for SHA, the Secure Hash Algorithm.
|
||||
|
||||
sha = [
|
||||
('abc', "a9993e364706816aba3e25717850c26c9cd0d89d"),
|
||||
('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq',
|
||||
"84983e441c3bd26ebaae4aa1f95129e5e54670f1"),
|
||||
(1000000 * 'a', '34aa973cd4c4daa4f61eeb2bdbad27316534016f'),
|
||||
]
|
||||
|
||||
sha256 = [
|
||||
('abc', "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"),
|
||||
("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
|
||||
"248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1"),
|
||||
("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
|
||||
"cf5b16a778af8380036ce59e7b0492370b249b11e8f07a51afac45037afee9d1"),
|
||||
("Four score and seven years ago our fathers brought forth on this continent, a new nation, conceived in Liberty, and dedicated to the proposition that all men are created equal. Now we are engaged in a great civil war, testing whether that nation, or any nation so conceived and so dedicated, can long endure. We are met on a great battlefield of that war. We have come to dedicate a portion of that field, as a final resting place for those who here gave their lives that that nation might live. It is altogether fitting and proper that we should do this. But, in a larger sense, we can not dedicate--we can not consecrate--we can not hallow--this ground. The brave men, living and dead, who struggled here, have consecrated it, far above our poor power to add or detract. The world will little note, nor long remember what we say here, but it can never forget what they did here. It is for us the living, rather, to be dedicated here to the unfinished work which they who fought here have thus far so nobly advanced. It is rather for us to be here dedicated to the great task remaining before us--that from these honored dead we take increased devotion to that cause for which they gave the last full measure of devotion--that we here highly resolve that these dead shall not have died in vain--that this nation, under God, shall have a new birth of freedom--and that government of the people, by the people, for the people, shall not perish from the earth. -- President Abraham Lincoln, November 19, 1863",
|
||||
"4d25fccf8752ce470a58cd21d90939b7eb25f3fa418dd2da4c38288ea561e600"),
|
||||
("", "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"),
|
||||
("This is exactly 64 bytes long, not counting the terminating byte", "ab64eff7e88e2e46165e29f2bce41826bd4c7b3552f6b382a9e7d3af47c245f8"),
|
||||
("For this sample, this 63-byte string will be used as input data", "f08a78cbbaee082b052ae0708f32fa1e50c5c421aa772ba5dbb406a2ea6be342"),
|
||||
("And this textual data, astonishing as it may appear, is exactly 128 bytes in length, as are both SHA-384 and SHA-512 block sizes",
|
||||
"0ab803344830f92089494fb635ad00d76164ad6e57012b237722df0d7ad26896"),
|
||||
("By hashing data that is one byte less than a multiple of a hash block length (like this 127-byte string), bugs may be revealed.",
|
||||
"e4326d0459653d7d3514674d713e74dc3df11ed4d30b4013fd327fdb9e394c26"),
|
||||
("qwerty" * 65536,
|
||||
"5e3dfe0cc98fd1c2de2a9d2fd893446da43d290f2512200c515416313cdf3192"),
|
||||
("Rijndael is AES" * 1024,
|
||||
"80fced5a97176a5009207cd119551b42c5b51ceb445230d02ecc2663bbfb483a"),
|
||||
(1000000 * 'a', 'cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0'),
|
||||
]
|
||||
|
||||
ripemd = [ ("", "9c1185a5c5e9fc54612808977ee8f548b2258d31"),
|
||||
("a", "0bdc9d2d256b3ee9daae347be6f4dc835a467ffe"),
|
||||
("abc", "8eb208f7e05d987a9b044a8e98c6b087f15a0bfc"),
|
||||
("message digest", "5d0689ef49d2fae572b881b123a85ffa21595f36"),
|
||||
("abcdefghijklmnopqrstuvwxyz",
|
||||
"f71c27109c692c1b56bbdceb5b9d2865b3708dbc"),
|
||||
("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
|
||||
"12a053384a9c0c88e405a06c27dcf49ada62eb2b"),
|
||||
("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
|
||||
"b0e20b6e3116640286ed3a87a5713079b21f5189"),
|
||||
(8 *"1234567890", "9b752e45573d4b39f4dbd3323cab82bf63326bfb"),
|
||||
(1000000 * 'a', "52783243c1697bdbe16d37f97f68f08325dc1528"),
|
||||
]
|
||||
|
||||
#Test data for SHA256
|
||||
sha256 = [("abc", "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"),
|
||||
("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
|
||||
"248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1"),
|
||||
("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
|
||||
"cf5b16a778af8380036ce59e7b0492370b249b11e8f07a51afac45037afee9d1"),
|
||||
("Four score and seven years ago our fathers brought forth on this continent, a new nation, conceived in Liberty, and dedicated to the proposition that all men are created equal. Now we are engaged in a great civil war, testing whether that nation, or any nation so conceived and so dedicated, can long endure. We are met on a great battlefield of that war. We have come to dedicate a portion of that field, as a final resting place for those who here gave their lives that that nation might live. It is altogether fitting and proper that we should do this. But, in a larger sense, we can not dedicate--we can not consecrate--we can not hallow--this ground. The brave men, living and dead, who struggled here, have consecrated it, far above our poor power to add or detract. The world will little note, nor long remember what we say here, but it can never forget what they did here. It is for us the living, rather, to be dedicated here to the unfinished work which they who fought here have thus far so nobly advanced. It is rather for us to be here dedicated to the great task remaining before us--that from these honored dead we take increased devotion to that cause for which they gave the last full measure of devotion--that we here highly resolve that these dead shall not have died in vain--that this nation, under God, shall have a new birth of freedom--and that government of the people, by the people, for the people, shall not perish from the earth. -- President Abraham Lincoln, November 19, 1863",
|
||||
"4d25fccf8752ce470a58cd21d90939b7eb25f3fa418dd2da4c38288ea561e600"),
|
||||
("", "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"),
|
||||
("This is exactly 64 bytes long, not counting the terminating byte", "ab64eff7e88e2e46165e29f2bce41826bd4c7b3552f6b382a9e7d3af47c245f8"),
|
||||
("For this sample, this 63-byte string will be used as input data", "f08a78cbbaee082b052ae0708f32fa1e50c5c421aa772ba5dbb406a2ea6be342"),
|
||||
("And this textual data, astonishing as it may appear, is exactly 128 bytes in length, as are both SHA-384 and SHA-512 block sizes",
|
||||
"0ab803344830f92089494fb635ad00d76164ad6e57012b237722df0d7ad26896"),
|
||||
("By hashing data that is one byte less than a multiple of a hash block length (like this 127-byte string), bugs may be revealed.",
|
||||
"e4326d0459653d7d3514674d713e74dc3df11ed4d30b4013fd327fdb9e394c26"),
|
||||
("qwerty" * 65536,
|
||||
"5e3dfe0cc98fd1c2de2a9d2fd893446da43d290f2512200c515416313cdf3192"),
|
||||
("Rijndael is AES" * 1024,
|
||||
"80fced5a97176a5009207cd119551b42c5b51ceb445230d02ecc2663bbfb483a"),
|
||||
]
|
||||
sha256 = sha256[:1]
|
||||
|
||||
# DES validation data
|
||||
|
||||
# Key, IV, plaintext, ciphertext
|
||||
des_cbc= [('0123456789abcdef', 'fedcba9876543210',
|
||||
"7654321 Now is the time for \000\000\000\000", 'ccd173ffab2039f4acd8aefddfd8a1eb468e91157888ba681d269397f7fe62b4')]
|
||||
|
||||
des = [ ('0000000000000000', '0000000000000000', '8CA64DE9C1B123A7'),
|
||||
('FFFFFFFFFFFFFFFF', 'FFFFFFFFFFFFFFFF', '7359B2163E4EDC58'),
|
||||
('3000000000000000', '1000000000000001', '958E6E627A05557B'),
|
||||
('1111111111111111', '1111111111111111', 'F40379AB9E0EC533'),
|
||||
('0123456789ABCDEF', '1111111111111111', '17668DFC7292532D'),
|
||||
('1111111111111111', '0123456789ABCDEF', '8A5AE1F81AB8F2DD'),
|
||||
('0000000000000000', '0000000000000000', '8CA64DE9C1B123A7'),
|
||||
('FEDCBA9876543210', '0123456789ABCDEF', 'ED39D950FA74BCC4'),
|
||||
('7CA110454A1A6E57', '01A1D6D039776742', '690F5B0D9A26939B'),
|
||||
('0131D9619DC1376E', '5CD54CA83DEF57DA', '7A389D10354BD271'),
|
||||
('07A1133E4A0B2686', '0248D43806F67172', '868EBB51CAB4599A'),
|
||||
('3849674C2602319E', '51454B582DDF440A', '7178876E01F19B2A'),
|
||||
('04B915BA43FEB5B6', '42FD443059577FA2', 'AF37FB421F8C4095'),
|
||||
('0113B970FD34F2CE', '059B5E0851CF143A', '86A560F10EC6D85B'),
|
||||
('0170F175468FB5E6', '0756D8E0774761D2', '0CD3DA020021DC09'),
|
||||
('43297FAD38E373FE', '762514B829BF486A', 'EA676B2CB7DB2B7A'),
|
||||
('07A7137045DA2A16', '3BDD119049372802', 'DFD64A815CAF1A0F'),
|
||||
('04689104C2FD3B2F', '26955F6835AF609A', '5C513C9C4886C088'),
|
||||
('37D06BB516CB7546', '164D5E404F275232', '0A2AEEAE3FF4AB77'),
|
||||
('1F08260D1AC2465E', '6B056E18759F5CCA', 'EF1BF03E5DFA575A'),
|
||||
('584023641ABA6176', '004BD6EF09176062', '88BF0DB6D70DEE56'),
|
||||
('025816164629B007', '480D39006EE762F2', 'A1F9915541020B56'),
|
||||
('49793EBC79B3258F', '437540C8698F3CFA', '6FBF1CAFCFFD0556'),
|
||||
('4FB05E1515AB73A7', '072D43A077075292', '2F22E49BAB7CA1AC'),
|
||||
('49E95D6D4CA229BF', '02FE55778117F12A', '5A6B612CC26CCE4A'),
|
||||
('018310DC409B26D6', '1D9D5C5018F728C2', '5F4C038ED12B2E41'),
|
||||
('1C587F1C13924FEF', '305532286D6F295A', '63FAC0D034D9F793'),
|
||||
('0101010101010101', '0123456789ABCDEF', '617B3A0CE8F07100'),
|
||||
('1F1F1F1F0E0E0E0E', '0123456789ABCDEF', 'DB958605F8C8C606'),
|
||||
('E0FEE0FEF1FEF1FE', '0123456789ABCDEF', 'EDBFD1C66C29CCC7'),
|
||||
('0000000000000000', 'FFFFFFFFFFFFFFFF', '355550B2150E2451'),
|
||||
('FFFFFFFFFFFFFFFF', '0000000000000000', 'CAAAAF4DEAF1DBAE'),
|
||||
('0123456789ABCDEF', '0000000000000000', 'D5D44FF720683D0D'),
|
||||
('FEDCBA9876543210', 'FFFFFFFFFFFFFFFF', '2A2BB008DF97C2F2'),
|
||||
('0101010101010101', '95F8A5E5DD31D900', '8000000000000000'),
|
||||
('0101010101010101', 'DD7F121CA5015619', '4000000000000000'),
|
||||
('0101010101010101', '2E8653104F3834EA', '2000000000000000'),
|
||||
('0101010101010101', '4BD388FF6CD81D4F', '1000000000000000'),
|
||||
('0101010101010101', '20B9E767B2FB1456', '0800000000000000'),
|
||||
('0101010101010101', '55579380D77138EF', '0400000000000000'),
|
||||
('0101010101010101', '6CC5DEFAAF04512F', '0200000000000000'),
|
||||
('0101010101010101', '0D9F279BA5D87260', '0100000000000000'),
|
||||
('0101010101010101', 'D9031B0271BD5A0A', '0080000000000000'),
|
||||
('0101010101010101', '424250B37C3DD951', '0040000000000000'),
|
||||
('0101010101010101', 'B8061B7ECD9A21E5', '0020000000000000'),
|
||||
('0101010101010101', 'F15D0F286B65BD28', '0010000000000000'),
|
||||
('0101010101010101', 'ADD0CC8D6E5DEBA1', '0008000000000000'),
|
||||
('0101010101010101', 'E6D5F82752AD63D1', '0004000000000000'),
|
||||
('0101010101010101', 'ECBFE3BD3F591A5E', '0002000000000000'),
|
||||
('0101010101010101', 'F356834379D165CD', '0001000000000000'),
|
||||
('0101010101010101', '2B9F982F20037FA9', '0000800000000000'),
|
||||
('0101010101010101', '889DE068A16F0BE6', '0000400000000000'),
|
||||
('0101010101010101', 'E19E275D846A1298', '0000200000000000'),
|
||||
('0101010101010101', '329A8ED523D71AEC', '0000100000000000'),
|
||||
('0101010101010101', 'E7FCE22557D23C97', '0000080000000000'),
|
||||
('0101010101010101', '12A9F5817FF2D65D', '0000040000000000'),
|
||||
('0101010101010101', 'A484C3AD38DC9C19', '0000020000000000'),
|
||||
('0101010101010101', 'FBE00A8A1EF8AD72', '0000010000000000'),
|
||||
('0101010101010101', '750D079407521363', '0000008000000000'),
|
||||
('0101010101010101', '64FEED9C724C2FAF', '0000004000000000'),
|
||||
('0101010101010101', 'F02B263B328E2B60', '0000002000000000'),
|
||||
('0101010101010101', '9D64555A9A10B852', '0000001000000000'),
|
||||
('0101010101010101', 'D106FF0BED5255D7', '0000000800000000'),
|
||||
('0101010101010101', 'E1652C6B138C64A5', '0000000400000000'),
|
||||
('0101010101010101', 'E428581186EC8F46', '0000000200000000'),
|
||||
('0101010101010101', 'AEB5F5EDE22D1A36', '0000000100000000'),
|
||||
('0101010101010101', 'E943D7568AEC0C5C', '0000000080000000'),
|
||||
('0101010101010101', 'DF98C8276F54B04B', '0000000040000000'),
|
||||
('0101010101010101', 'B160E4680F6C696F', '0000000020000000'),
|
||||
('0101010101010101', 'FA0752B07D9C4AB8', '0000000010000000'),
|
||||
('0101010101010101', 'CA3A2B036DBC8502', '0000000008000000'),
|
||||
('0101010101010101', '5E0905517BB59BCF', '0000000004000000'),
|
||||
('0101010101010101', '814EEB3B91D90726', '0000000002000000'),
|
||||
('0101010101010101', '4D49DB1532919C9F', '0000000001000000'),
|
||||
('0101010101010101', '25EB5FC3F8CF0621', '0000000000800000'),
|
||||
('0101010101010101', 'AB6A20C0620D1C6F', '0000000000400000'),
|
||||
('0101010101010101', '79E90DBC98F92CCA', '0000000000200000'),
|
||||
('0101010101010101', '866ECEDD8072BB0E', '0000000000100000'),
|
||||
('0101010101010101', '8B54536F2F3E64A8', '0000000000080000'),
|
||||
('0101010101010101', 'EA51D3975595B86B', '0000000000040000'),
|
||||
('0101010101010101', 'CAFFC6AC4542DE31', '0000000000020000'),
|
||||
('0101010101010101', '8DD45A2DDF90796C', '0000000000010000'),
|
||||
('0101010101010101', '1029D55E880EC2D0', '0000000000008000'),
|
||||
('0101010101010101', '5D86CB23639DBEA9', '0000000000004000'),
|
||||
('0101010101010101', '1D1CA853AE7C0C5F', '0000000000002000'),
|
||||
('0101010101010101', 'CE332329248F3228', '0000000000001000'),
|
||||
('0101010101010101', '8405D1ABE24FB942', '0000000000000800'),
|
||||
('0101010101010101', 'E643D78090CA4207', '0000000000000400'),
|
||||
('0101010101010101', '48221B9937748A23', '0000000000000200'),
|
||||
('0101010101010101', 'DD7C0BBD61FAFD54', '0000000000000100'),
|
||||
('0101010101010101', '2FBC291A570DB5C4', '0000000000000080'),
|
||||
('0101010101010101', 'E07C30D7E4E26E12', '0000000000000040'),
|
||||
('0101010101010101', '0953E2258E8E90A1', '0000000000000020'),
|
||||
('0101010101010101', '5B711BC4CEEBF2EE', '0000000000000010'),
|
||||
('0101010101010101', 'CC083F1E6D9E85F6', '0000000000000008'),
|
||||
('0101010101010101', 'D2FD8867D50D2DFE', '0000000000000004'),
|
||||
('0101010101010101', '06E7EA22CE92708F', '0000000000000002'),
|
||||
('0101010101010101', '166B40B44ABA4BD6', '0000000000000001'),
|
||||
('8001010101010101', '0000000000000000', '95A8D72813DAA94D'),
|
||||
('4001010101010101', '0000000000000000', '0EEC1487DD8C26D5'),
|
||||
('2001010101010101', '0000000000000000', '7AD16FFB79C45926'),
|
||||
('1001010101010101', '0000000000000000', 'D3746294CA6A6CF3'),
|
||||
('0801010101010101', '0000000000000000', '809F5F873C1FD761'),
|
||||
('0401010101010101', '0000000000000000', 'C02FAFFEC989D1FC'),
|
||||
('0201010101010101', '0000000000000000', '4615AA1D33E72F10'),
|
||||
('0180010101010101', '0000000000000000', '2055123350C00858'),
|
||||
('0140010101010101', '0000000000000000', 'DF3B99D6577397C8'),
|
||||
('0120010101010101', '0000000000000000', '31FE17369B5288C9'),
|
||||
('0110010101010101', '0000000000000000', 'DFDD3CC64DAE1642'),
|
||||
('0108010101010101', '0000000000000000', '178C83CE2B399D94'),
|
||||
('0104010101010101', '0000000000000000', '50F636324A9B7F80'),
|
||||
('0102010101010101', '0000000000000000', 'A8468EE3BC18F06D'),
|
||||
('0101800101010101', '0000000000000000', 'A2DC9E92FD3CDE92'),
|
||||
('0101400101010101', '0000000000000000', 'CAC09F797D031287'),
|
||||
('0101200101010101', '0000000000000000', '90BA680B22AEB525'),
|
||||
('0101100101010101', '0000000000000000', 'CE7A24F350E280B6'),
|
||||
('0101080101010101', '0000000000000000', '882BFF0AA01A0B87'),
|
||||
('0101040101010101', '0000000000000000', '25610288924511C2'),
|
||||
('0101020101010101', '0000000000000000', 'C71516C29C75D170'),
|
||||
('0101018001010101', '0000000000000000', '5199C29A52C9F059'),
|
||||
('0101014001010101', '0000000000000000', 'C22F0A294A71F29F'),
|
||||
('0101012001010101', '0000000000000000', 'EE371483714C02EA'),
|
||||
('0101011001010101', '0000000000000000', 'A81FBD448F9E522F'),
|
||||
('0101010801010101', '0000000000000000', '4F644C92E192DFED'),
|
||||
('0101010401010101', '0000000000000000', '1AFA9A66A6DF92AE'),
|
||||
('0101010201010101', '0000000000000000', 'B3C1CC715CB879D8'),
|
||||
('0101010180010101', '0000000000000000', '19D032E64AB0BD8B'),
|
||||
('0101010140010101', '0000000000000000', '3CFAA7A7DC8720DC'),
|
||||
('0101010120010101', '0000000000000000', 'B7265F7F447AC6F3'),
|
||||
('0101010110010101', '0000000000000000', '9DB73B3C0D163F54'),
|
||||
('0101010108010101', '0000000000000000', '8181B65BABF4A975'),
|
||||
('0101010104010101', '0000000000000000', '93C9B64042EAA240'),
|
||||
('0101010102010101', '0000000000000000', '5570530829705592'),
|
||||
('0101010101800101', '0000000000000000', '8638809E878787A0'),
|
||||
('0101010101400101', '0000000000000000', '41B9A79AF79AC208'),
|
||||
('0101010101200101', '0000000000000000', '7A9BE42F2009A892'),
|
||||
('0101010101100101', '0000000000000000', '29038D56BA6D2745'),
|
||||
('0101010101080101', '0000000000000000', '5495C6ABF1E5DF51'),
|
||||
('0101010101040101', '0000000000000000', 'AE13DBD561488933'),
|
||||
('0101010101020101', '0000000000000000', '024D1FFA8904E389'),
|
||||
('0101010101018001', '0000000000000000', 'D1399712F99BF02E'),
|
||||
('0101010101014001', '0000000000000000', '14C1D7C1CFFEC79E'),
|
||||
('0101010101012001', '0000000000000000', '1DE5279DAE3BED6F'),
|
||||
('0101010101011001', '0000000000000000', 'E941A33F85501303'),
|
||||
('0101010101010801', '0000000000000000', 'DA99DBBC9A03F379'),
|
||||
('0101010101010401', '0000000000000000', 'B7FC92F91D8E92E9'),
|
||||
('0101010101010201', '0000000000000000', 'AE8E5CAA3CA04E85'),
|
||||
('0101010101010180', '0000000000000000', '9CC62DF43B6EED74'),
|
||||
('0101010101010140', '0000000000000000', 'D863DBB5C59A91A0'),
|
||||
('0101010101010120', '0000000000000000', 'A1AB2190545B91D7'),
|
||||
('0101010101010110', '0000000000000000', '0875041E64C570F7'),
|
||||
('0101010101010108', '0000000000000000', '5A594528BEBEF1CC'),
|
||||
('0101010101010104', '0000000000000000', 'FCDB3291DE21F0C0'),
|
||||
('0101010101010102', '0000000000000000', '869EFD7F9F265A09'),
|
||||
('1046913489980131', '0000000000000000', '88D55E54F54C97B4'),
|
||||
('1007103489988020', '0000000000000000', '0C0CC00C83EA48FD'),
|
||||
('10071034C8980120', '0000000000000000', '83BC8EF3A6570183'),
|
||||
('1046103489988020', '0000000000000000', 'DF725DCAD94EA2E9'),
|
||||
('1086911519190101', '0000000000000000', 'E652B53B550BE8B0'),
|
||||
('1086911519580101', '0000000000000000', 'AF527120C485CBB0'),
|
||||
('5107B01519580101', '0000000000000000', '0F04CE393DB926D5'),
|
||||
('1007B01519190101', '0000000000000000', 'C9F00FFC74079067'),
|
||||
('3107915498080101', '0000000000000000', '7CFD82A593252B4E'),
|
||||
('3107919498080101', '0000000000000000', 'CB49A2F9E91363E3'),
|
||||
('10079115B9080140', '0000000000000000', '00B588BE70D23F56'),
|
||||
('3107911598080140', '0000000000000000', '406A9A6AB43399AE'),
|
||||
('1007D01589980101', '0000000000000000', '6CB773611DCA9ADA'),
|
||||
('9107911589980101', '0000000000000000', '67FD21C17DBB5D70'),
|
||||
('9107D01589190101', '0000000000000000', '9592CB4110430787'),
|
||||
('1007D01598980120', '0000000000000000', 'A6B7FF68A318DDD3'),
|
||||
('1007940498190101', '0000000000000000', '4D102196C914CA16'),
|
||||
('0107910491190401', '0000000000000000', '2DFA9F4573594965'),
|
||||
('0107910491190101', '0000000000000000', 'B46604816C0E0774'),
|
||||
('0107940491190401', '0000000000000000', '6E7E6221A4F34E87'),
|
||||
('19079210981A0101', '0000000000000000', 'AA85E74643233199'),
|
||||
('1007911998190801', '0000000000000000', '2E5A19DB4D1962D6'),
|
||||
('10079119981A0801', '0000000000000000', '23A866A809D30894'),
|
||||
('1007921098190101', '0000000000000000', 'D812D961F017D320'),
|
||||
('100791159819010B', '0000000000000000', '055605816E58608F'),
|
||||
('1004801598190101', '0000000000000000', 'ABD88E8B1B7716F1'),
|
||||
('1004801598190102', '0000000000000000', '537AC95BE69DA1E1'),
|
||||
('1004801598190108', '0000000000000000', 'AED0F6AE3C25CDD8'),
|
||||
('1002911598100104', '0000000000000000', 'B3E35A5EE53E7B8D'),
|
||||
('1002911598190104', '0000000000000000', '61C79C71921A2EF8'),
|
||||
('1002911598100201', '0000000000000000', 'E2F5728F0995013C'),
|
||||
('1002911698100101', '0000000000000000', '1AEAC39A61F0A464'),
|
||||
('7CA110454A1A6E57', '01A1D6D039776742', '690F5B0D9A26939B'),
|
||||
('0131D9619DC1376E', '5CD54CA83DEF57DA', '7A389D10354BD271'),
|
||||
('07A1133E4A0B2686', '0248D43806F67172', '868EBB51CAB4599A'),
|
||||
('3849674C2602319E', '51454B582DDF440A', '7178876E01F19B2A'),
|
||||
('04B915BA43FEB5B6', '42FD443059577FA2', 'AF37FB421F8C4095'),
|
||||
('0113B970FD34F2CE', '059B5E0851CF143A', '86A560F10EC6D85B'),
|
||||
('0170F175468FB5E6', '0756D8E0774761D2', '0CD3DA020021DC09'),
|
||||
('43297FAD38E373FE', '762514B829BF486A', 'EA676B2CB7DB2B7A'),
|
||||
('07A7137045DA2A16', '3BDD119049372802', 'DFD64A815CAF1A0F'),
|
||||
('04689104C2FD3B2F', '26955F6835AF609A', '5C513C9C4886C088'),
|
||||
('37D06BB516CB7546', '164D5E404F275232', '0A2AEEAE3FF4AB77'),
|
||||
('1F08260D1AC2465E', '6B056E18759F5CCA', 'EF1BF03E5DFA575A'),
|
||||
('584023641ABA6176', '004BD6EF09176062', '88BF0DB6D70DEE56'),
|
||||
('025816164629B007', '480D39006EE762F2', 'A1F9915541020B56'),
|
||||
('49793EBC79B3258F', '437540C8698F3CFA', '6FBF1CAFCFFD0556'),
|
||||
('4FB05E1515AB73A7', '072D43A077075292', '2F22E49BAB7CA1AC'),
|
||||
('49E95D6D4CA229BF', '02FE55778117F12A', '5A6B612CC26CCE4A'),
|
||||
('018310DC409B26D6', '1D9D5C5018F728C2', '5F4C038ED12B2E41'),
|
||||
('1C587F1C13924FEF', '305532286D6F295A', '63FAC0D034D9F793') ]
|
||||
|
||||
|
||||
# Test data for Alleged RC4
|
||||
|
||||
arc4 = [ ('0000000000000000', '0000000000000000', 'de188941a3375d3a'),
|
||||
('0123456789abcdef', '0123456789abcdef', '75b7878099e0c596'),
|
||||
('0123456789abcdef', '0000000000000000', '7494c2e7104b0879'),
|
||||
('ef012345', '00000000000000000000', 'd6a141a7ec3c38dfbd61') ]
|
||||
|
||||
# Test data for IDEA
|
||||
|
||||
idea = [('00010002000300040005000600070008', '0000000100020003', '11fbed2b01986de5'),
|
||||
('00010002000300040005000600070008', '0102030405060708', '540E5FEA18C2F8B1'),
|
||||
('00010002000300040005000600070008', '0019324B647D96AF', '9F0A0AB6E10CED78'),
|
||||
('00010002000300040005000600070008', 'F5202D5B9C671B08', 'CF18FD7355E2C5C5'),
|
||||
('00010002000300040005000600070008', 'FAE6D2BEAA96826E', '85DF52005608193D'),
|
||||
('00010002000300040005000600070008', '0A141E28323C4650', '2F7DE750212FB734'),
|
||||
('00010002000300040005000600070008', '050A0F14191E2328', '7B7314925DE59C09'),
|
||||
('0005000A000F00140019001E00230028', '0102030405060708', '3EC04780BEFF6E20'),
|
||||
('3A984E2000195DB32EE501C8C47CEA60', '0102030405060708', '97BCD8200780DA86'),
|
||||
('006400C8012C019001F4025802BC0320', '05320A6414C819FA', '65BE87E7A2538AED'),
|
||||
('9D4075C103BC322AFB03E7BE6AB30006', '0808080808080808', 'F5DB1AC45E5EF9F9')
|
||||
];
|
||||
|
||||
# Test data for RC5
|
||||
|
||||
rc5 = [('10200c1000000000000000000000000000000000', '0000000000000000',
|
||||
'21A5DBEE154B8F6D'),
|
||||
('10200c10915F4619BE41B2516355A50110A9CE91', '21A5DBEE154B8F6D',
|
||||
'F7C013AC5B2B8952'),
|
||||
('10200c10783348E75AEB0F2FD7B169BB8DC16787', 'F7C013AC5B2B8952',
|
||||
'2F42B3B70369FC92'),
|
||||
('10200c10DC49DB1375A5584F6485B413B5F12BAF', '2F42B3B70369FC92',
|
||||
'65C178B284D197CC'),
|
||||
('10200c105269F149D41BA0152497574D7F153125', '65C178B284D197CC',
|
||||
'EB44E415DA319824')
|
||||
]
|
||||
|
||||
# Test data for ARC2
|
||||
arc2 = [
|
||||
('5068696c6970476c617373', '0000000000000000', '624fb3e887419e48'),
|
||||
('5068696c6970476c617373', 'ffffffffffffffff', '79cadef44c4a5a85'),
|
||||
('5068696c6970476c617373', '0001020304050607', '90411525b34e4c2c'),
|
||||
('5068696c6970476c617373', '0011223344556677', '078656aaba61cbfb'),
|
||||
('ffffffffffffffff', '0000000000000000', 'd7bcc5dbb4d6e56a'),
|
||||
('ffffffffffffffff', 'ffffffffffffffff', '7259018ec557b357'),
|
||||
('ffffffffffffffff', '0001020304050607', '93d20a497f2ccb62'),
|
||||
('ffffffffffffffff', '0011223344556677', 'cb15a7f819c0014d'),
|
||||
('ffffffffffffffff5065746572477265656e6177617953e5ffe553', '0000000000000000', '63ac98cdf3843a7a'),
|
||||
('ffffffffffffffff5065746572477265656e6177617953e5ffe553', 'ffffffffffffffff', '3fb49e2fa12371dd'),
|
||||
('ffffffffffffffff5065746572477265656e6177617953e5ffe553', '0001020304050607', '46414781ab387d5f'),
|
||||
('ffffffffffffffff5065746572477265656e6177617953e5ffe553', '0011223344556677', 'be09dc81feaca271'),
|
||||
('53e5ffe553', '0000000000000000', 'e64221e608be30ab'),
|
||||
('53e5ffe553', 'ffffffffffffffff', '862bc60fdcd4d9a9'),
|
||||
('53e5ffe553', '0001020304050607', '6a34da50fa5e47de'),
|
||||
('53e5ffe553', '0011223344556677', '584644c34503122c'),
|
||||
]
|
||||
|
||||
# Test data for Blowfish
|
||||
|
||||
blowfish = [('6162636465666768696a6b6c6d6e6f707172737475767778797a',
|
||||
'424c4f5746495348', '324ed0fef413a203'),
|
||||
('57686f206973204a6f686e2047616c743f', 'fedcba9876543210',
|
||||
'cc91732b8022f684')
|
||||
]
|
||||
|
||||
# Test data for DES3
|
||||
|
||||
des3_cbc=[]
|
||||
|
||||
des3= [('0123456789abcdeffedcba9876543210', '0123456789abcde7',
|
||||
'7f1d0a77826b8aff'),
|
||||
]
|
||||
|
||||
# The DES test data can also be used to construct DES3 test data.
|
||||
for key, iv, plain, cipher in des_cbc:
|
||||
des3_cbc.append((key*3, iv, plain, cipher))
|
||||
for key, plain, cipher in des:
|
||||
des3.append((key*3, plain, cipher))
|
||||
|
||||
# Test data for CAST
|
||||
|
||||
_castkey = '0123456712345678234567893456789A'
|
||||
_castdata = '0123456789ABCDEF'
|
||||
|
||||
cast = [(_castkey, _castdata, '238B4FE5847E44B2'),
|
||||
(_castkey[:10*2], _castdata, 'EB6A711A2C02271B'),
|
||||
(_castkey[: 5*2], _castdata, '7AC816D16E9B302E'),
|
||||
]
|
||||
|
||||
# Test data for XOR
|
||||
|
||||
xor = []
|
||||
|
||||
# Test data for AES
|
||||
|
||||
aes = [# 128-bit key
|
||||
('000102030405060708090A0B0C0D0E0F',
|
||||
'00112233445566778899AABBCCDDEEFF',
|
||||
'69C4E0D86A7B0430D8CDB78070B4C55A'),
|
||||
|
||||
# 192-bit key
|
||||
('000102030405060708090A0B0C0D0E0F1011121314151617',
|
||||
'00112233445566778899AABBCCDDEEFF',
|
||||
'DDA97CA4864CDFE06EAF70A0EC0D7191'),
|
||||
|
||||
# 256-bit key
|
||||
('000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F',
|
||||
'00112233445566778899AABBCCDDEEFF',
|
||||
'8EA2B7CA516745BFEAFC49904B496089'),
|
||||
]
|
||||
|
||||
# Test data for AES modes, from NIST SP800-38A
|
||||
from allmydata.Crypto.Cipher import AES
|
||||
|
||||
counterstart='\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff'
|
||||
|
||||
aes_modes = [
|
||||
(AES.MODE_CBC,
|
||||
'2b7e151628aed2a6abf7158809cf4f3c',
|
||||
('6bc1bee22e409f96e93d7e117393172a'
|
||||
'ae2d8a571e03ac9c9eb76fac45af8e51'
|
||||
'30c81c46a35ce411e5fbc1191a0a52ef'
|
||||
'f69f2445df4f9b17ad2b417be66c3710'
|
||||
),
|
||||
('7649abac8119b246cee98e9b12e9197d'
|
||||
'5086cb9b507219ee95db113a917678b2'
|
||||
'73bed6b8e3c1743b7116e69e22229516'
|
||||
'3ff1caa1681fac09120eca307586e1a7'
|
||||
),
|
||||
{'IV':'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f'} ),
|
||||
(AES.MODE_CBC,
|
||||
'8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b',
|
||||
('6bc1bee22e409f96e93d7e117393172a'
|
||||
'ae2d8a571e03ac9c9eb76fac45af8e51'
|
||||
'30c81c46a35ce411e5fbc1191a0a52ef'
|
||||
'f69f2445df4f9b17ad2b417be66c3710'
|
||||
),
|
||||
('4f021db243bc633d7178183a9fa071e8'
|
||||
'b4d9ada9ad7dedf4e5e738763f69145a'
|
||||
'571b242012fb7ae07fa9baac3df102e0'
|
||||
'08b0e27988598881d920a9e64f5615cd'
|
||||
),
|
||||
{'IV':'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f'} ),
|
||||
(AES.MODE_CBC,
|
||||
('603deb1015ca71be2b73aef0857d7781'
|
||||
'1f352c073b6108d72d9810a30914dff4'
|
||||
),
|
||||
('6bc1bee22e409f96e93d7e117393172a'
|
||||
'ae2d8a571e03ac9c9eb76fac45af8e51'
|
||||
'30c81c46a35ce411e5fbc1191a0a52ef'
|
||||
'f69f2445df4f9b17ad2b417be66c3710'
|
||||
),
|
||||
('f58c4c04d6e5f1ba779eabfb5f7bfbd6'
|
||||
'9cfc4e967edb808d679f777bc6702c7d'
|
||||
'39f23369a9d9bacfa530e26304231461'
|
||||
'b2eb05e2c39be9fcda6c19078c6a9d1b'
|
||||
),
|
||||
{'IV':'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f'} ),
|
||||
|
||||
(AES.MODE_OFB,
|
||||
('2b7e151628aed2a6abf7158809cf4f3c'
|
||||
),
|
||||
('6bc1bee22e409f96e93d7e117393172a'
|
||||
'ae2d8a571e03ac9c9eb76fac45af8e51'
|
||||
'30c81c46a35ce411e5fbc1191a0a52ef'
|
||||
'f69f2445df4f9b17ad2b417be66c3710'
|
||||
),
|
||||
('3b3fd92eb72dad20333449f8e83cfb4a'
|
||||
'7789508d16918f03f53c52dac54ed825'
|
||||
'9740051e9c5fecf64344f7a82260edcc'
|
||||
'304c6528f659c77866a510d9c1d6ae5e'
|
||||
),
|
||||
{'IV':'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f'} ),
|
||||
(AES.MODE_OFB,
|
||||
('8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b'
|
||||
),
|
||||
('6bc1bee22e409f96e93d7e117393172a'
|
||||
'ae2d8a571e03ac9c9eb76fac45af8e51'
|
||||
'30c81c46a35ce411e5fbc1191a0a52ef'
|
||||
'f69f2445df4f9b17ad2b417be66c3710'
|
||||
),
|
||||
('cdc80d6fddf18cab34c25909c99a4174'
|
||||
'fcc28b8d4c63837c09e81700c1100401'
|
||||
'8d9a9aeac0f6596f559c6d4daf59a5f2'
|
||||
'6d9f200857ca6c3e9cac524bd9acc92a'
|
||||
),
|
||||
{'IV':'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f'} ),
|
||||
(AES.MODE_OFB,
|
||||
('603deb1015ca71be2b73aef0857d7781'
|
||||
'1f352c073b6108d72d9810a30914dff4'
|
||||
),
|
||||
('6bc1bee22e409f96e93d7e117393172a'
|
||||
'ae2d8a571e03ac9c9eb76fac45af8e51'
|
||||
'30c81c46a35ce411e5fbc1191a0a52ef'
|
||||
'f69f2445df4f9b17ad2b417be66c3710'
|
||||
),
|
||||
('dc7e84bfda79164b7ecd8486985d3860'
|
||||
'4febdc6740d20b3ac88f6ad82a4fb08d'
|
||||
'71ab47a086e86eedf39d1c5bba97c408'
|
||||
'0126141d67f37be8538f5a8be740e484'
|
||||
),
|
||||
{'IV':'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f'} ),
|
||||
|
||||
(AES.MODE_CTR,
|
||||
('2b7e151628aed2a6abf7158809cf4f3c'
|
||||
),
|
||||
('6bc1bee22e409f96e93d7e117393172a'
|
||||
'ae2d8a571e03ac9c9eb76fac45af8e51'
|
||||
'30c81c46a35ce411e5fbc1191a0a52ef'
|
||||
'f69f2445df4f9b17ad2b417be66c3710'
|
||||
),
|
||||
('874d6191b620e3261bef6864990db6ce'
|
||||
'9806f66b7970fdff8617187bb9fffdff'
|
||||
'5ae4df3edbd5d35e5b4f09020db03eab'
|
||||
'1e031dda2fbe03d1792170a0f3009cee'
|
||||
),
|
||||
{'counterstart': counterstart}, ),
|
||||
(AES.MODE_CTR,
|
||||
('8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b'
|
||||
),
|
||||
('6bc1bee22e409f96e93d7e117393172a'
|
||||
'ae2d8a571e03ac9c9eb76fac45af8e51'
|
||||
'30c81c46a35ce411e5fbc1191a0a52ef'
|
||||
'f69f2445df4f9b17ad2b417be66c3710'
|
||||
),
|
||||
('1abc932417521ca24f2b0459fe7e6e0b'
|
||||
'090339ec0aa6faefd5ccc2c6f4ce8e94'
|
||||
'1e36b26bd1ebc670d1bd1d665620abf7'
|
||||
'4f78a7f6d29809585a97daec58c6b050'
|
||||
),
|
||||
{'counterstart': counterstart}, ),
|
||||
(AES.MODE_CTR,
|
||||
('603deb1015ca71be2b73aef0857d7781'
|
||||
'1f352c073b6108d72d9810a30914dff4'
|
||||
),
|
||||
('6bc1bee22e409f96e93d7e117393172a'
|
||||
'ae2d8a571e03ac9c9eb76fac45af8e51'
|
||||
'30c81c46a35ce411e5fbc1191a0a52ef'
|
||||
'f69f2445df4f9b17ad2b417be66c3710'
|
||||
),
|
||||
('601ec313775789a5b7a7f504bbf3d228'
|
||||
'f443e3ca4d62b59aca84e990cacaf5c5'
|
||||
'2b0930daa23de94ce87017ba2d84988d'
|
||||
'dfc9c58db67aada613c2dd08457941a6'
|
||||
),
|
||||
{'counterstart': counterstart}, ),
|
||||
|
||||
(AES.MODE_CFB,
|
||||
'2b7e151628aed2a6abf7158809cf4f3c',
|
||||
'6bc1bee22e409f96e93d7e117393172aae2d',
|
||||
'3b79424c9c0dd436bace9e0ed4586a4f32b9',
|
||||
{'segment_size':8,
|
||||
'IV':'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f',
|
||||
}
|
||||
),
|
||||
(AES.MODE_CFB,
|
||||
'8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b',
|
||||
'6bc1bee22e409f96e93d7e117393172aae2d',
|
||||
'cda2521ef0a905ca44cd057cbf0d47a0678a',
|
||||
{'segment_size':8,
|
||||
'IV':'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f',
|
||||
}
|
||||
),
|
||||
(AES.MODE_CFB,
|
||||
('603deb1015ca71be2b73aef0857d7781'
|
||||
'1f352c073b6108d72d9810a30914dff4'
|
||||
),
|
||||
'6bc1bee22e409f96e93d7e117393172aae2d',
|
||||
'dc1f1a8520a64db55fcc8ac554844e889700',
|
||||
{'segment_size':8,
|
||||
'IV':'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f',
|
||||
}
|
||||
),
|
||||
|
||||
(AES.MODE_CFB,
|
||||
('2b7e151628aed2a6abf7158809cf4f3c'
|
||||
),
|
||||
('6bc1bee22e409f96e93d7e117393172a'
|
||||
'ae2d8a571e03ac9c9eb76fac45af8e51'
|
||||
'30c81c46a35ce411e5fbc1191a0a52ef'
|
||||
'f69f2445df4f9b17ad2b417be66c3710'
|
||||
),
|
||||
(
|
||||
'3b3fd92eb72dad20333449f8e83cfb4a'
|
||||
'c8a64537a0b3a93fcde3cdad9f1ce58b'
|
||||
'26751f67a3cbb140b1808cf187a4f4df'
|
||||
'c04b05357c5d1c0eeac4c66f9ff7f2e6'
|
||||
),
|
||||
{'segment_size':128,
|
||||
'IV':'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f',
|
||||
}
|
||||
),
|
||||
(AES.MODE_CFB,
|
||||
('8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b'
|
||||
),
|
||||
('6bc1bee22e409f96e93d7e117393172a'
|
||||
'ae2d8a571e03ac9c9eb76fac45af8e51'
|
||||
'30c81c46a35ce411e5fbc1191a0a52ef'
|
||||
'f69f2445df4f9b17ad2b417be66c3710'
|
||||
),
|
||||
(
|
||||
'cdc80d6fddf18cab34c25909c99a4174'
|
||||
'67ce7f7f81173621961a2b70171d3d7a'
|
||||
'2e1e8a1dd59b88b1c8e60fed1efac4c9'
|
||||
'c05f9f9ca9834fa042ae8fba584b09ff'
|
||||
),
|
||||
{'segment_size':128,
|
||||
'IV':'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f',
|
||||
}
|
||||
),
|
||||
(AES.MODE_CFB,
|
||||
('603deb1015ca71be2b73aef0857d7781'
|
||||
'1f352c073b6108d72d9810a30914dff4'
|
||||
),
|
||||
('6bc1bee22e409f96e93d7e117393172a'
|
||||
'ae2d8a571e03ac9c9eb76fac45af8e51'
|
||||
'30c81c46a35ce411e5fbc1191a0a52ef'
|
||||
'f69f2445df4f9b17ad2b417be66c3710'
|
||||
),
|
||||
(
|
||||
'dc7e84bfda79164b7ecd8486985d3860'
|
||||
'39ffed143b28b1c832113c6331e5407b'
|
||||
'df10132415e54b92a13ed0a8267ae2f9'
|
||||
'75a385741ab9cef82031623d55b1e471'
|
||||
),
|
||||
{'segment_size':128,
|
||||
'IV':'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f',
|
||||
}
|
||||
),
|
||||
]
|
0
src/allmydata/Crypto/Cipher/__init__.py
Normal file
0
src/allmydata/Crypto/Cipher/__init__.py
Normal file
0
src/allmydata/Crypto/Hash/__init__.py
Normal file
0
src/allmydata/Crypto/Hash/__init__.py
Normal file
@ -1,3 +1,11 @@
|
||||
|
||||
This directory contains pieces of the PyCrypto package. We've copied just the
|
||||
parts we need (AES with zooko's fast-CTR-mode patch, SHA256, Util.number, and
|
||||
eventually RSA) into the tahoe tree.
|
||||
|
||||
|
||||
PyCrypto is published with the following license:
|
||||
|
||||
===================================================================
|
||||
Distribute and use freely; there are no restrictions on further
|
||||
dissemination and usage except those imposed by the laws of your
|
||||
@ -13,3 +21,4 @@ not have to make source available or contribute your changes back
|
||||
--amk (www.amk.ca)
|
||||
|
||||
|
||||
|
0
src/allmydata/Crypto/Util/__init__.py
Normal file
0
src/allmydata/Crypto/Util/__init__.py
Normal file
4
src/allmydata/Crypto/__init__.py
Normal file
4
src/allmydata/Crypto/__init__.py
Normal file
@ -0,0 +1,4 @@
|
||||
#! /usr/bin/python
|
||||
|
||||
# we also need to provide bytes_to_long, normally from
|
||||
# allmydata.Crypto.Util.number.bytes_to_long
|
Loading…
x
Reference in New Issue
Block a user