Igor Zhukov
10 years ago
62 changed files with 4626 additions and 1080 deletions
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 13 KiB |
@ -0,0 +1,147 @@ |
|||||||
|
/* crypto/aes/aes.h -*- mode:C; c-file-style: "eay" -*- */ |
||||||
|
/* ====================================================================
|
||||||
|
* Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions |
||||||
|
* are met: |
||||||
|
* |
||||||
|
* 1. Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* |
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer in |
||||||
|
* the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* |
||||||
|
* 3. All advertising materials mentioning features or use of this |
||||||
|
* software must display the following acknowledgment: |
||||||
|
* "This product includes software developed by the OpenSSL Project |
||||||
|
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||||
|
* |
||||||
|
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to |
||||||
|
* endorse or promote products derived from this software without |
||||||
|
* prior written permission. For written permission, please contact |
||||||
|
* openssl-core@openssl.org. |
||||||
|
* |
||||||
|
* 5. Products derived from this software may not be called "OpenSSL" |
||||||
|
* nor may "OpenSSL" appear in their names without prior written |
||||||
|
* permission of the OpenSSL Project. |
||||||
|
* |
||||||
|
* 6. Redistributions of any form whatsoever must retain the following |
||||||
|
* acknowledgment: |
||||||
|
* "This product includes software developed by the OpenSSL Project |
||||||
|
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY |
||||||
|
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR |
||||||
|
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* ==================================================================== |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef HEADER_AES_H |
||||||
|
#define HEADER_AES_H |
||||||
|
|
||||||
|
//#include <openssl/opensslconf.h>
|
||||||
|
|
||||||
|
#ifdef OPENSSL_NO_AES |
||||||
|
#error AES is disabled. |
||||||
|
#endif |
||||||
|
|
||||||
|
#include <stddef.h> |
||||||
|
|
||||||
|
#define AES_ENCRYPT 1 |
||||||
|
#define AES_DECRYPT 0 |
||||||
|
|
||||||
|
/* Because array size can't be a const in C, the following two are macros.
|
||||||
|
Both sizes are in bytes. */ |
||||||
|
#define AES_MAXNR 14 |
||||||
|
#define AES_BLOCK_SIZE 16 |
||||||
|
|
||||||
|
#ifdef __cplusplus |
||||||
|
extern "C" { |
||||||
|
#endif |
||||||
|
|
||||||
|
/* This should be a hidden type, but EVP requires that the size be known */ |
||||||
|
struct aes_key_st { |
||||||
|
#ifdef AES_LONG |
||||||
|
unsigned long rd_key[4 *(AES_MAXNR + 1)]; |
||||||
|
#else |
||||||
|
unsigned int rd_key[4 *(AES_MAXNR + 1)]; |
||||||
|
#endif |
||||||
|
int rounds; |
||||||
|
}; |
||||||
|
typedef struct aes_key_st AES_KEY; |
||||||
|
|
||||||
|
const char *AES_options(void); |
||||||
|
|
||||||
|
int AES_set_encrypt_key(const unsigned char *userKey, const int bits, |
||||||
|
AES_KEY *key); |
||||||
|
int AES_set_decrypt_key(const unsigned char *userKey, const int bits, |
||||||
|
AES_KEY *key); |
||||||
|
|
||||||
|
int private_AES_set_encrypt_key(const unsigned char *userKey, const int bits, |
||||||
|
AES_KEY *key); |
||||||
|
int private_AES_set_decrypt_key(const unsigned char *userKey, const int bits, |
||||||
|
AES_KEY *key); |
||||||
|
|
||||||
|
void AES_encrypt(const unsigned char *in, unsigned char *out, |
||||||
|
const AES_KEY *key); |
||||||
|
void AES_decrypt(const unsigned char *in, unsigned char *out, |
||||||
|
const AES_KEY *key); |
||||||
|
|
||||||
|
void AES_ecb_encrypt(const unsigned char *in, unsigned char *out, |
||||||
|
const AES_KEY *key, const int enc); |
||||||
|
void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, |
||||||
|
size_t length, const AES_KEY *key, |
||||||
|
unsigned char *ivec, const int enc); |
||||||
|
void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out, |
||||||
|
size_t length, const AES_KEY *key, |
||||||
|
unsigned char *ivec, int *num, const int enc); |
||||||
|
void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out, |
||||||
|
size_t length, const AES_KEY *key, |
||||||
|
unsigned char *ivec, int *num, const int enc); |
||||||
|
void AES_cfb8_encrypt(const unsigned char *in, unsigned char *out, |
||||||
|
size_t length, const AES_KEY *key, |
||||||
|
unsigned char *ivec, int *num, const int enc); |
||||||
|
void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out, |
||||||
|
size_t length, const AES_KEY *key, |
||||||
|
unsigned char *ivec, int *num); |
||||||
|
void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, |
||||||
|
size_t length, const AES_KEY *key, |
||||||
|
unsigned char ivec[AES_BLOCK_SIZE], |
||||||
|
unsigned char ecount_buf[AES_BLOCK_SIZE], |
||||||
|
unsigned int *num); |
||||||
|
/* NB: the IV is _two_ blocks long */ |
||||||
|
void AES_ige_encrypt(const unsigned char *in, unsigned char *out, |
||||||
|
size_t length, const AES_KEY *key, |
||||||
|
unsigned char *ivec, const int enc); |
||||||
|
/* NB: the IV is _four_ blocks long */ |
||||||
|
void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out, |
||||||
|
size_t length, const AES_KEY *key, |
||||||
|
const AES_KEY *key2, const unsigned char *ivec, |
||||||
|
const int enc); |
||||||
|
|
||||||
|
int AES_wrap_key(AES_KEY *key, const unsigned char *iv, |
||||||
|
unsigned char *out, |
||||||
|
const unsigned char *in, unsigned int inlen); |
||||||
|
int AES_unwrap_key(AES_KEY *key, const unsigned char *iv, |
||||||
|
unsigned char *out, |
||||||
|
const unsigned char *in, unsigned int inlen); |
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
#endif /* !HEADER_AES_H */ |
@ -0,0 +1,325 @@ |
|||||||
|
/* crypto/aes/aes_ige.c -*- mode:C; c-file-style: "eay" -*- */ |
||||||
|
/* ====================================================================
|
||||||
|
* Copyright (c) 2006 The OpenSSL Project. All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions |
||||||
|
* are met: |
||||||
|
* |
||||||
|
* 1. Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* |
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer in |
||||||
|
* the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* |
||||||
|
* 3. All advertising materials mentioning features or use of this |
||||||
|
* software must display the following acknowledgment: |
||||||
|
* "This product includes software developed by the OpenSSL Project |
||||||
|
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||||
|
* |
||||||
|
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to |
||||||
|
* endorse or promote products derived from this software without |
||||||
|
* prior written permission. For written permission, please contact |
||||||
|
* openssl-core@openssl.org. |
||||||
|
* |
||||||
|
* 5. Products derived from this software may not be called "OpenSSL" |
||||||
|
* nor may "OpenSSL" appear in their names without prior written |
||||||
|
* permission of the OpenSSL Project. |
||||||
|
* |
||||||
|
* 6. Redistributions of any form whatsoever must retain the following |
||||||
|
* acknowledgment: |
||||||
|
* "This product includes software developed by the OpenSSL Project |
||||||
|
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY |
||||||
|
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR |
||||||
|
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* ==================================================================== |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
//#include "cryptlib.h"
|
||||||
|
|
||||||
|
#include "aes.h" |
||||||
|
#include "aes_locl.h" |
||||||
|
#include <assert.h> |
||||||
|
#define OPENSSL_assert assert |
||||||
|
|
||||||
|
#define N_WORDS (AES_BLOCK_SIZE / sizeof(unsigned long)) |
||||||
|
typedef struct { |
||||||
|
unsigned long data[N_WORDS]; |
||||||
|
} aes_block_t; |
||||||
|
|
||||||
|
/* XXX: probably some better way to do this */ |
||||||
|
#if defined(__i386__) || defined(__x86_64__) |
||||||
|
#define UNALIGNED_MEMOPS_ARE_FAST 1 |
||||||
|
#else |
||||||
|
#define UNALIGNED_MEMOPS_ARE_FAST 0 |
||||||
|
#endif |
||||||
|
|
||||||
|
#if UNALIGNED_MEMOPS_ARE_FAST |
||||||
|
#define load_block(d, s) (d) = *(const aes_block_t *)(s) |
||||||
|
#define store_block(d, s) *(aes_block_t *)(d) = (s) |
||||||
|
#else |
||||||
|
#define load_block(d, s) memcpy((d).data, (s), AES_BLOCK_SIZE) |
||||||
|
#define store_block(d, s) memcpy((d), (s).data, AES_BLOCK_SIZE) |
||||||
|
#endif |
||||||
|
|
||||||
|
/* N.B. The IV for this mode is _twice_ the block size */ |
||||||
|
|
||||||
|
void AES_ige_encrypt(const unsigned char *in, unsigned char *out, |
||||||
|
size_t length, const AES_KEY *key, |
||||||
|
unsigned char *ivec, const int enc) |
||||||
|
{ |
||||||
|
size_t n; |
||||||
|
size_t len = length; |
||||||
|
|
||||||
|
OPENSSL_assert(in && out && key && ivec); |
||||||
|
OPENSSL_assert((AES_ENCRYPT == enc)||(AES_DECRYPT == enc)); |
||||||
|
OPENSSL_assert((length%AES_BLOCK_SIZE) == 0); |
||||||
|
|
||||||
|
len = length / AES_BLOCK_SIZE; |
||||||
|
|
||||||
|
if (AES_ENCRYPT == enc) |
||||||
|
{ |
||||||
|
if (in != out && |
||||||
|
(UNALIGNED_MEMOPS_ARE_FAST || ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(long)==0)) |
||||||
|
{ |
||||||
|
aes_block_t *ivp = (aes_block_t *)ivec; |
||||||
|
aes_block_t *iv2p = (aes_block_t *)(ivec + AES_BLOCK_SIZE); |
||||||
|
|
||||||
|
while (len) |
||||||
|
{ |
||||||
|
aes_block_t *inp = (aes_block_t *)in; |
||||||
|
aes_block_t *outp = (aes_block_t *)out; |
||||||
|
|
||||||
|
for(n=0 ; n < N_WORDS; ++n) |
||||||
|
outp->data[n] = inp->data[n] ^ ivp->data[n]; |
||||||
|
AES_encrypt((unsigned char *)outp->data, (unsigned char *)outp->data, key); |
||||||
|
for(n=0 ; n < N_WORDS; ++n) |
||||||
|
outp->data[n] ^= iv2p->data[n]; |
||||||
|
ivp = outp; |
||||||
|
iv2p = inp; |
||||||
|
--len; |
||||||
|
in += AES_BLOCK_SIZE; |
||||||
|
out += AES_BLOCK_SIZE; |
||||||
|
} |
||||||
|
memcpy(ivec, ivp->data, AES_BLOCK_SIZE); |
||||||
|
memcpy(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
aes_block_t tmp, tmp2; |
||||||
|
aes_block_t iv; |
||||||
|
aes_block_t iv2; |
||||||
|
|
||||||
|
load_block(iv, ivec); |
||||||
|
load_block(iv2, ivec + AES_BLOCK_SIZE); |
||||||
|
|
||||||
|
while (len) |
||||||
|
{ |
||||||
|
load_block(tmp, in); |
||||||
|
for(n=0 ; n < N_WORDS; ++n) |
||||||
|
tmp2.data[n] = tmp.data[n] ^ iv.data[n]; |
||||||
|
AES_encrypt((unsigned char *)tmp2.data, (unsigned char *)tmp2.data, key); |
||||||
|
for(n=0 ; n < N_WORDS; ++n) |
||||||
|
tmp2.data[n] ^= iv2.data[n]; |
||||||
|
store_block(out, tmp2); |
||||||
|
iv = tmp2; |
||||||
|
iv2 = tmp; |
||||||
|
--len; |
||||||
|
in += AES_BLOCK_SIZE; |
||||||
|
out += AES_BLOCK_SIZE; |
||||||
|
} |
||||||
|
memcpy(ivec, iv.data, AES_BLOCK_SIZE); |
||||||
|
memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE); |
||||||
|
} |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
if (in != out && |
||||||
|
(UNALIGNED_MEMOPS_ARE_FAST || ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(long)==0)) |
||||||
|
{ |
||||||
|
aes_block_t *ivp = (aes_block_t *)ivec; |
||||||
|
aes_block_t *iv2p = (aes_block_t *)(ivec + AES_BLOCK_SIZE); |
||||||
|
|
||||||
|
while (len) |
||||||
|
{ |
||||||
|
aes_block_t tmp; |
||||||
|
aes_block_t *inp = (aes_block_t *)in; |
||||||
|
aes_block_t *outp = (aes_block_t *)out; |
||||||
|
|
||||||
|
for(n=0 ; n < N_WORDS; ++n) |
||||||
|
tmp.data[n] = inp->data[n] ^ iv2p->data[n]; |
||||||
|
AES_decrypt((unsigned char *)tmp.data, (unsigned char *)outp->data, key); |
||||||
|
for(n=0 ; n < N_WORDS; ++n) |
||||||
|
outp->data[n] ^= ivp->data[n]; |
||||||
|
ivp = inp; |
||||||
|
iv2p = outp; |
||||||
|
--len; |
||||||
|
in += AES_BLOCK_SIZE; |
||||||
|
out += AES_BLOCK_SIZE; |
||||||
|
} |
||||||
|
memcpy(ivec, ivp->data, AES_BLOCK_SIZE); |
||||||
|
memcpy(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
aes_block_t tmp, tmp2; |
||||||
|
aes_block_t iv; |
||||||
|
aes_block_t iv2; |
||||||
|
|
||||||
|
load_block(iv, ivec); |
||||||
|
load_block(iv2, ivec + AES_BLOCK_SIZE); |
||||||
|
|
||||||
|
while (len) |
||||||
|
{ |
||||||
|
load_block(tmp, in); |
||||||
|
tmp2 = tmp; |
||||||
|
for(n=0 ; n < N_WORDS; ++n) |
||||||
|
tmp.data[n] ^= iv2.data[n]; |
||||||
|
AES_decrypt((unsigned char *)tmp.data, (unsigned char *)tmp.data, key); |
||||||
|
for(n=0 ; n < N_WORDS; ++n) |
||||||
|
tmp.data[n] ^= iv.data[n]; |
||||||
|
store_block(out, tmp); |
||||||
|
iv = tmp2; |
||||||
|
iv2 = tmp; |
||||||
|
--len; |
||||||
|
in += AES_BLOCK_SIZE; |
||||||
|
out += AES_BLOCK_SIZE; |
||||||
|
} |
||||||
|
memcpy(ivec, iv.data, AES_BLOCK_SIZE); |
||||||
|
memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/*
|
||||||
|
* Note that its effectively impossible to do biIGE in anything other |
||||||
|
* than a single pass, so no provision is made for chaining. |
||||||
|
*/ |
||||||
|
|
||||||
|
/* N.B. The IV for this mode is _four times_ the block size */ |
||||||
|
|
||||||
|
void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out, |
||||||
|
size_t length, const AES_KEY *key, |
||||||
|
const AES_KEY *key2, const unsigned char *ivec, |
||||||
|
const int enc) |
||||||
|
{ |
||||||
|
size_t n; |
||||||
|
size_t len = length; |
||||||
|
unsigned char tmp[AES_BLOCK_SIZE]; |
||||||
|
unsigned char tmp2[AES_BLOCK_SIZE]; |
||||||
|
unsigned char tmp3[AES_BLOCK_SIZE]; |
||||||
|
unsigned char prev[AES_BLOCK_SIZE]; |
||||||
|
const unsigned char *iv; |
||||||
|
const unsigned char *iv2; |
||||||
|
|
||||||
|
OPENSSL_assert(in && out && key && ivec); |
||||||
|
OPENSSL_assert((AES_ENCRYPT == enc)||(AES_DECRYPT == enc)); |
||||||
|
OPENSSL_assert((length%AES_BLOCK_SIZE) == 0); |
||||||
|
|
||||||
|
if (AES_ENCRYPT == enc) |
||||||
|
{ |
||||||
|
/* XXX: Do a separate case for when in != out (strictly should
|
||||||
|
check for overlap, too) */ |
||||||
|
|
||||||
|
/* First the forward pass */ |
||||||
|
iv = ivec; |
||||||
|
iv2 = ivec + AES_BLOCK_SIZE; |
||||||
|
while (len >= AES_BLOCK_SIZE) |
||||||
|
{ |
||||||
|
for(n=0 ; n < AES_BLOCK_SIZE ; ++n) |
||||||
|
out[n] = in[n] ^ iv[n]; |
||||||
|
AES_encrypt(out, out, key); |
||||||
|
for(n=0 ; n < AES_BLOCK_SIZE ; ++n) |
||||||
|
out[n] ^= iv2[n]; |
||||||
|
iv = out; |
||||||
|
memcpy(prev, in, AES_BLOCK_SIZE); |
||||||
|
iv2 = prev; |
||||||
|
len -= AES_BLOCK_SIZE; |
||||||
|
in += AES_BLOCK_SIZE; |
||||||
|
out += AES_BLOCK_SIZE; |
||||||
|
} |
||||||
|
|
||||||
|
/* And now backwards */ |
||||||
|
iv = ivec + AES_BLOCK_SIZE*2; |
||||||
|
iv2 = ivec + AES_BLOCK_SIZE*3; |
||||||
|
len = length; |
||||||
|
while(len >= AES_BLOCK_SIZE) |
||||||
|
{ |
||||||
|
out -= AES_BLOCK_SIZE; |
||||||
|
/* XXX: reduce copies by alternating between buffers */ |
||||||
|
memcpy(tmp, out, AES_BLOCK_SIZE); |
||||||
|
for(n=0 ; n < AES_BLOCK_SIZE ; ++n) |
||||||
|
out[n] ^= iv[n]; |
||||||
|
/* hexdump(stdout, "out ^ iv", out, AES_BLOCK_SIZE); */ |
||||||
|
AES_encrypt(out, out, key); |
||||||
|
/* hexdump(stdout,"enc", out, AES_BLOCK_SIZE); */ |
||||||
|
/* hexdump(stdout,"iv2", iv2, AES_BLOCK_SIZE); */ |
||||||
|
for(n=0 ; n < AES_BLOCK_SIZE ; ++n) |
||||||
|
out[n] ^= iv2[n]; |
||||||
|
/* hexdump(stdout,"out", out, AES_BLOCK_SIZE); */ |
||||||
|
iv = out; |
||||||
|
memcpy(prev, tmp, AES_BLOCK_SIZE); |
||||||
|
iv2 = prev; |
||||||
|
len -= AES_BLOCK_SIZE; |
||||||
|
} |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
/* First backwards */ |
||||||
|
iv = ivec + AES_BLOCK_SIZE*2; |
||||||
|
iv2 = ivec + AES_BLOCK_SIZE*3; |
||||||
|
in += length; |
||||||
|
out += length; |
||||||
|
while (len >= AES_BLOCK_SIZE) |
||||||
|
{ |
||||||
|
in -= AES_BLOCK_SIZE; |
||||||
|
out -= AES_BLOCK_SIZE; |
||||||
|
memcpy(tmp, in, AES_BLOCK_SIZE); |
||||||
|
memcpy(tmp2, in, AES_BLOCK_SIZE); |
||||||
|
for(n=0 ; n < AES_BLOCK_SIZE ; ++n) |
||||||
|
tmp[n] ^= iv2[n]; |
||||||
|
AES_decrypt(tmp, out, key); |
||||||
|
for(n=0 ; n < AES_BLOCK_SIZE ; ++n) |
||||||
|
out[n] ^= iv[n]; |
||||||
|
memcpy(tmp3, tmp2, AES_BLOCK_SIZE); |
||||||
|
iv = tmp3; |
||||||
|
iv2 = out; |
||||||
|
len -= AES_BLOCK_SIZE; |
||||||
|
} |
||||||
|
|
||||||
|
/* And now forwards */ |
||||||
|
iv = ivec; |
||||||
|
iv2 = ivec + AES_BLOCK_SIZE; |
||||||
|
len = length; |
||||||
|
while (len >= AES_BLOCK_SIZE) |
||||||
|
{ |
||||||
|
memcpy(tmp, out, AES_BLOCK_SIZE); |
||||||
|
memcpy(tmp2, out, AES_BLOCK_SIZE); |
||||||
|
for(n=0 ; n < AES_BLOCK_SIZE ; ++n) |
||||||
|
tmp[n] ^= iv2[n]; |
||||||
|
AES_decrypt(tmp, out, key); |
||||||
|
for(n=0 ; n < AES_BLOCK_SIZE ; ++n) |
||||||
|
out[n] ^= iv[n]; |
||||||
|
memcpy(tmp3, tmp2, AES_BLOCK_SIZE); |
||||||
|
iv = tmp3; |
||||||
|
iv2 = out; |
||||||
|
len -= AES_BLOCK_SIZE; |
||||||
|
in += AES_BLOCK_SIZE; |
||||||
|
out += AES_BLOCK_SIZE; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,89 @@ |
|||||||
|
/* crypto/aes/aes.h -*- mode:C; c-file-style: "eay" -*- */ |
||||||
|
/* ====================================================================
|
||||||
|
* Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions |
||||||
|
* are met: |
||||||
|
* |
||||||
|
* 1. Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* |
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer in |
||||||
|
* the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* |
||||||
|
* 3. All advertising materials mentioning features or use of this |
||||||
|
* software must display the following acknowledgment: |
||||||
|
* "This product includes software developed by the OpenSSL Project |
||||||
|
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||||
|
* |
||||||
|
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to |
||||||
|
* endorse or promote products derived from this software without |
||||||
|
* prior written permission. For written permission, please contact |
||||||
|
* openssl-core@openssl.org. |
||||||
|
* |
||||||
|
* 5. Products derived from this software may not be called "OpenSSL" |
||||||
|
* nor may "OpenSSL" appear in their names without prior written |
||||||
|
* permission of the OpenSSL Project. |
||||||
|
* |
||||||
|
* 6. Redistributions of any form whatsoever must retain the following |
||||||
|
* acknowledgment: |
||||||
|
* "This product includes software developed by the OpenSSL Project |
||||||
|
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY |
||||||
|
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR |
||||||
|
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* ==================================================================== |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef HEADER_AES_LOCL_H |
||||||
|
#define HEADER_AES_LOCL_H |
||||||
|
|
||||||
|
//#include <openssl/e_os2.h>
|
||||||
|
|
||||||
|
#ifdef OPENSSL_NO_AES |
||||||
|
#error AES is disabled. |
||||||
|
#endif |
||||||
|
|
||||||
|
#include <stdio.h> |
||||||
|
#include <stdlib.h> |
||||||
|
#include <string.h> |
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64)) |
||||||
|
# define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00) |
||||||
|
# define GETU32(p) SWAP(*((u32 *)(p))) |
||||||
|
# define PUTU32(ct, st) { *((u32 *)(ct)) = SWAP((st)); } |
||||||
|
#else |
||||||
|
# define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3])) |
||||||
|
# define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); } |
||||||
|
#endif |
||||||
|
|
||||||
|
#ifdef AES_LONG |
||||||
|
typedef unsigned long u32; |
||||||
|
#else |
||||||
|
typedef unsigned int u32; |
||||||
|
#endif |
||||||
|
typedef unsigned short u16; |
||||||
|
typedef unsigned char u8; |
||||||
|
|
||||||
|
#define MAXKC (256/32) |
||||||
|
#define MAXKB (256/8) |
||||||
|
#define MAXNR 14 |
||||||
|
|
||||||
|
/* This controls loop-unrolling in aes_core.c */ |
||||||
|
#undef FULL_UNROLL |
||||||
|
|
||||||
|
#endif /* !HEADER_AES_LOCL_H */ |
@ -0,0 +1,85 @@ |
|||||||
|
/* crypto/aes/aes_misc.c -*- mode:C; c-file-style: "eay" -*- */ |
||||||
|
/* ====================================================================
|
||||||
|
* Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions |
||||||
|
* are met: |
||||||
|
* |
||||||
|
* 1. Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* |
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer in |
||||||
|
* the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* |
||||||
|
* 3. All advertising materials mentioning features or use of this |
||||||
|
* software must display the following acknowledgment: |
||||||
|
* "This product includes software developed by the OpenSSL Project |
||||||
|
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||||
|
* |
||||||
|
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to |
||||||
|
* endorse or promote products derived from this software without |
||||||
|
* prior written permission. For written permission, please contact |
||||||
|
* openssl-core@openssl.org. |
||||||
|
* |
||||||
|
* 5. Products derived from this software may not be called "OpenSSL" |
||||||
|
* nor may "OpenSSL" appear in their names without prior written |
||||||
|
* permission of the OpenSSL Project. |
||||||
|
* |
||||||
|
* 6. Redistributions of any form whatsoever must retain the following |
||||||
|
* acknowledgment: |
||||||
|
* "This product includes software developed by the OpenSSL Project |
||||||
|
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY |
||||||
|
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR |
||||||
|
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* ==================================================================== |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
//#include <openssl/opensslv.h>
|
||||||
|
//#include <openssl/crypto.h>
|
||||||
|
#include "aes.h" |
||||||
|
#include "aes_locl.h" |
||||||
|
|
||||||
|
const char AES_version[]="AES" ;//OPENSSL_VERSION_PTEXT;
|
||||||
|
|
||||||
|
const char *AES_options(void) { |
||||||
|
#ifdef FULL_UNROLL |
||||||
|
return "aes(full)"; |
||||||
|
#else |
||||||
|
return "aes(partial)"; |
||||||
|
#endif |
||||||
|
} |
||||||
|
|
||||||
|
/* FIPS wrapper functions to block low level AES calls in FIPS mode */ |
||||||
|
|
||||||
|
int AES_set_encrypt_key(const unsigned char *userKey, const int bits, |
||||||
|
AES_KEY *key) |
||||||
|
{ |
||||||
|
#ifdef OPENSSL_FIPS |
||||||
|
fips_cipher_abort(AES); |
||||||
|
#endif |
||||||
|
return private_AES_set_encrypt_key(userKey, bits, key); |
||||||
|
} |
||||||
|
|
||||||
|
int AES_set_decrypt_key(const unsigned char *userKey, const int bits, |
||||||
|
AES_KEY *key) |
||||||
|
{ |
||||||
|
#ifdef OPENSSL_FIPS |
||||||
|
fips_cipher_abort(AES); |
||||||
|
#endif |
||||||
|
return private_AES_set_decrypt_key(userKey, bits, key); |
||||||
|
} |
Binary file not shown.
@ -0,0 +1,267 @@ |
|||||||
|
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
/// @file hello_tutorial.cc
|
||||||
|
/// This example demonstrates loading, running and scripting a very simple NaCl
|
||||||
|
/// module. To load the NaCl module, the browser first looks for the
|
||||||
|
/// CreateModule() factory method (at the end of this file). It calls
|
||||||
|
/// CreateModule() once to load the module code. After the code is loaded,
|
||||||
|
/// CreateModule() is not called again.
|
||||||
|
///
|
||||||
|
/// Once the code is loaded, the browser calls the CreateInstance()
|
||||||
|
/// method on the object returned by CreateModule(). It calls CreateInstance()
|
||||||
|
/// each time it encounters an <embed> tag that references your NaCl module.
|
||||||
|
///
|
||||||
|
/// The browser can talk to your NaCl module via the postMessage() Javascript
|
||||||
|
/// function. When you call postMessage() on your NaCl module from the browser,
|
||||||
|
/// this becomes a call to the HandleMessage() method of your pp::Instance
|
||||||
|
/// subclass. You can send messages back to the browser by calling the
|
||||||
|
/// PostMessage() method on your pp::Instance. Note that these two methods
|
||||||
|
/// (postMessage() in Javascript and PostMessage() in C++) are asynchronous.
|
||||||
|
/// This means they return immediately - there is no waiting for the message
|
||||||
|
/// to be handled. This has implications in your program design, particularly
|
||||||
|
/// when mutating property values that are exposed to both the browser and the
|
||||||
|
/// NaCl module.
|
||||||
|
|
||||||
|
#include "ppapi/cpp/instance.h" |
||||||
|
#include "ppapi/cpp/module.h" |
||||||
|
#include "ppapi/cpp/var.h" |
||||||
|
#include "ppapi/cpp/var_dictionary.h" |
||||||
|
#include "ppapi/cpp/var_array_buffer.h" |
||||||
|
#include "aes.h" |
||||||
|
#include <inttypes.h> |
||||||
|
#include <stdio.h> |
||||||
|
|
||||||
|
|
||||||
|
uint64_t gcd(uint64_t a, uint64_t b) { |
||||||
|
while (a != 0 && b != 0) { |
||||||
|
while ((b & 1) == 0) { |
||||||
|
b >>= 1; |
||||||
|
} |
||||||
|
while ((a & 1) == 0) { |
||||||
|
a >>= 1; |
||||||
|
} |
||||||
|
if (a > b) { |
||||||
|
a -= b; |
||||||
|
} else { |
||||||
|
b -= a; |
||||||
|
} |
||||||
|
} |
||||||
|
return b == 0 ? a : b; |
||||||
|
} |
||||||
|
|
||||||
|
/// The Instance class. One of these exists for each instance of your NaCl
|
||||||
|
/// module on the web page. The browser will ask the Module object to create
|
||||||
|
/// a new Instance for each occurrence of the <embed> tag that has these
|
||||||
|
/// attributes:
|
||||||
|
/// src="hello_tutorial.nmf"
|
||||||
|
/// type="application/x-pnacl"
|
||||||
|
/// To communicate with the browser, you must override HandleMessage() to
|
||||||
|
/// receive messages from the browser, and use PostMessage() to send messages
|
||||||
|
/// back to the browser. Note that this interface is asynchronous.
|
||||||
|
class MtprotoCryptoInstance : public pp::Instance { |
||||||
|
public: |
||||||
|
/// The constructor creates the plugin-side instance.
|
||||||
|
/// @param[in] instance the handle to the browser-side plugin instance.
|
||||||
|
explicit MtprotoCryptoInstance(PP_Instance instance) : pp::Instance(instance) |
||||||
|
{} |
||||||
|
|
||||||
|
virtual ~MtprotoCryptoInstance() {} |
||||||
|
|
||||||
|
/// Handler for messages coming in from the browser via postMessage(). The
|
||||||
|
/// @a var_message can contain be any pp:Var type; for example int, string
|
||||||
|
/// Array or Dictinary. Please see the pp:Var documentation for more details.
|
||||||
|
/// @param[in] var_message The message posted by the browser.
|
||||||
|
virtual void HandleMessage(const pp::Var& var_message) { |
||||||
|
|
||||||
|
if (!var_message.is_dictionary()) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
pp::VarDictionary request = pp::VarDictionary::VarDictionary(var_message); |
||||||
|
|
||||||
|
pp::Var varTaskID = request.Get(pp::Var::Var("taskID")); |
||||||
|
pp::Var varTask = request.Get(pp::Var::Var("task")); |
||||||
|
if (!varTaskID.is_int()) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
int32_t intTaskID = varTaskID.AsInt(); |
||||||
|
std::string strTask = varTask.AsString(); |
||||||
|
pp::Var varResult; |
||||||
|
|
||||||
|
if (strTask == "aes-encrypt") { |
||||||
|
pp::Var varData = request.Get(pp::Var::Var("bytes")); |
||||||
|
pp::Var varKey = request.Get(pp::Var::Var("keyBytes")); |
||||||
|
pp::Var varIv = request.Get(pp::Var::Var("ivBytes")); |
||||||
|
|
||||||
|
if (!varData.is_array_buffer() || !varKey.is_array_buffer() || !varIv.is_array_buffer()) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
pp::VarArrayBuffer abData = pp::VarArrayBuffer::VarArrayBuffer(varData); |
||||||
|
pp::VarArrayBuffer abKey = pp::VarArrayBuffer::VarArrayBuffer(varKey); |
||||||
|
pp::VarArrayBuffer abIv = pp::VarArrayBuffer::VarArrayBuffer(varIv); |
||||||
|
|
||||||
|
char* what = static_cast<char*>(abData.Map()); |
||||||
|
char* keyBuff = static_cast<char*>(abKey.Map()); |
||||||
|
char* ivBuff = static_cast<char*>(abIv.Map()); |
||||||
|
int length = abData.ByteLength(); |
||||||
|
|
||||||
|
AES_KEY akey; |
||||||
|
AES_set_encrypt_key((const unsigned char *) keyBuff, 32 * 8, &akey); |
||||||
|
AES_ige_encrypt((const unsigned char *)what, (unsigned char *)what, length, &akey, (unsigned char *)ivBuff, AES_ENCRYPT); |
||||||
|
|
||||||
|
varResult = abData; |
||||||
|
|
||||||
|
} |
||||||
|
else if (strTask == "aes-decrypt") { |
||||||
|
pp::Var varData = request.Get(pp::Var::Var("encryptedBytes")); |
||||||
|
pp::Var varKey = request.Get(pp::Var::Var("keyBytes")); |
||||||
|
pp::Var varIv = request.Get(pp::Var::Var("ivBytes")); |
||||||
|
|
||||||
|
if (!varData.is_array_buffer() || !varKey.is_array_buffer() || !varIv.is_array_buffer()) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
pp::VarArrayBuffer abData = pp::VarArrayBuffer::VarArrayBuffer(varData); |
||||||
|
pp::VarArrayBuffer abKey = pp::VarArrayBuffer::VarArrayBuffer(varKey); |
||||||
|
pp::VarArrayBuffer abIv = pp::VarArrayBuffer::VarArrayBuffer(varIv); |
||||||
|
|
||||||
|
char* what = static_cast<char*>(abData.Map()); |
||||||
|
char* keyBuff = static_cast<char*>(abKey.Map()); |
||||||
|
char* ivBuff = static_cast<char*>(abIv.Map()); |
||||||
|
int length = abData.ByteLength(); |
||||||
|
|
||||||
|
AES_KEY akey; |
||||||
|
AES_set_decrypt_key((const unsigned char *) keyBuff, 32 * 8, &akey); |
||||||
|
AES_ige_encrypt((const unsigned char *)what, (unsigned char *)what, length, &akey, (unsigned char *)ivBuff, AES_DECRYPT); |
||||||
|
|
||||||
|
varResult = abData; |
||||||
|
|
||||||
|
} |
||||||
|
else if (strTask == "factorize") { |
||||||
|
|
||||||
|
pp::Var varBytes = request.Get(pp::Var::Var("bytes")); |
||||||
|
if (!varBytes.is_array()) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
pp::VarArray aBytes = pp::VarArray::VarArray(varBytes); |
||||||
|
int length = aBytes.GetLength(); |
||||||
|
if (length > 8) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
uint64_t what = 0; |
||||||
|
for (int i = 0; i < length; i++) { |
||||||
|
what += (uint64_t) aBytes.Get(length - i - 1).AsInt() << (i * 8); |
||||||
|
} |
||||||
|
|
||||||
|
int it = 0, i, j; |
||||||
|
uint64_t g = 0; |
||||||
|
for (i = 0; i < 3 || it < 1000; i++) { |
||||||
|
int q = ((lrand48() & 15) + 17) % what; |
||||||
|
uint64_t x = (long long)lrand48() % (what - 1) + 1, y = x; |
||||||
|
int lim = 1 << (i + 18), j; |
||||||
|
for(j = 1; j < lim; j++) { |
||||||
|
++it; |
||||||
|
uint64_t a = x, b = x, c = q; |
||||||
|
while (b) { |
||||||
|
if (b & 1) { |
||||||
|
c += a; |
||||||
|
if (c >= what) { |
||||||
|
c -= what; |
||||||
|
} |
||||||
|
} |
||||||
|
a += a; |
||||||
|
if (a >= what) { |
||||||
|
a -= what; |
||||||
|
} |
||||||
|
b >>= 1; |
||||||
|
} |
||||||
|
x = c; |
||||||
|
uint64_t z = x < y ? what + x - y : x - y; |
||||||
|
g = gcd(z, what); |
||||||
|
if (g != 1) { |
||||||
|
break; |
||||||
|
} |
||||||
|
if (!(j & (j - 1))) { |
||||||
|
y = x; |
||||||
|
} |
||||||
|
} |
||||||
|
if (g > 1 && g < what) { |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
uint64_t p = what / g; |
||||||
|
pp::VarArray pBytesArray = pp::VarArray::VarArray(); |
||||||
|
int index = 0; |
||||||
|
for (int i = 0; i < 8; i++) { |
||||||
|
unsigned char byte = p >> ((8 - i - 1) * 8) & 0xFF; |
||||||
|
if (byte > 0 || index > 0) { |
||||||
|
pBytesArray.Set(index, pp::Var::Var((int)byte)); |
||||||
|
index++; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
index = 0; |
||||||
|
pp::VarArray gBytesArray = pp::VarArray::VarArray(); |
||||||
|
for (i = 0; i < 8; i++) { |
||||||
|
unsigned char byte = g >> ((8 - i - 1) * 8) & 0xFF; |
||||||
|
if (byte > 0 || index > 0) { |
||||||
|
gBytesArray.Set(index, pp::Var::Var((int)byte)); |
||||||
|
index++; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
pp::VarArray varResultArray = pp::VarArray::VarArray(); |
||||||
|
if (p < g) { |
||||||
|
varResultArray.Set(0, pBytesArray); |
||||||
|
varResultArray.Set(1, gBytesArray); |
||||||
|
} else { |
||||||
|
varResultArray.Set(1, pBytesArray); |
||||||
|
varResultArray.Set(0, gBytesArray); |
||||||
|
} |
||||||
|
|
||||||
|
varResult = varResultArray; |
||||||
|
} |
||||||
|
else { |
||||||
|
varResult = pp::Var::Var(); |
||||||
|
} |
||||||
|
|
||||||
|
pp::VarDictionary response = pp::VarDictionary::VarDictionary(); |
||||||
|
response.Set(pp::Var::Var("taskID"), varTaskID); |
||||||
|
response.Set(pp::Var::Var("result"), varResult); |
||||||
|
|
||||||
|
PostMessage(response); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
/// The Module class. The browser calls the CreateInstance() method to create
|
||||||
|
/// an instance of your NaCl module on the web page. The browser creates a new
|
||||||
|
/// instance for each <embed> tag with type="application/x-pnacl".
|
||||||
|
class MtprotoCryptoModule : public pp::Module { |
||||||
|
public: |
||||||
|
MtprotoCryptoModule() : pp::Module() {} |
||||||
|
virtual ~MtprotoCryptoModule() {} |
||||||
|
|
||||||
|
/// Create and return a MtprotoCryptoInstance object.
|
||||||
|
/// @param[in] instance The browser-side instance.
|
||||||
|
/// @return the plugin-side instance.
|
||||||
|
virtual pp::Instance* CreateInstance(PP_Instance instance) { |
||||||
|
return new MtprotoCryptoInstance(instance); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
namespace pp { |
||||||
|
/// Factory function called by the browser when the module is first loaded.
|
||||||
|
/// The browser keeps a singleton of this module. It calls the
|
||||||
|
/// CreateInstance() method on the object you return to make instances. There
|
||||||
|
/// is one instance per <embed> tag on the page. This is the main binding
|
||||||
|
/// point for your NaCl module with the browser.
|
||||||
|
Module* CreateModule() { |
||||||
|
return new MtprotoCryptoModule(); |
||||||
|
} |
||||||
|
} // namespace pp
|
@ -0,0 +1,10 @@ |
|||||||
|
{ |
||||||
|
"program": { |
||||||
|
"portable": { |
||||||
|
"pnacl-translate": { |
||||||
|
"url": "mtproto_crypto.pexe?67", |
||||||
|
"optlevel": 2 |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
Binary file not shown.
@ -1,31 +1,39 @@ |
|||||||
<div class="audio_player_wrap clearfix"> |
<div class="audio_player_wrap clearfix"> |
||||||
<button class="btn btn-primary pull-left audio_player_button" ng-click="togglePlay()"> |
<a class="im_message_file_button" ng-click="togglePlay()" ng-class="{im_message_file_button_dl_audio: audio.downloaded}"> |
||||||
<i class="icon audio_player_btn_icon" ng-class="{audio_player_btn_icon_pause: mediaPlayer.player.playing, audio_player_btn_icon_cancel: audio.progress.enabled}"></i> |
<i class="im_message_file_button_icon" ng-class="{audio_player_btn_icon_pause: mediaPlayer.player.playing}"></i> |
||||||
</button> |
</a> |
||||||
<div class="audio_player_title_wrap"> |
<div class="audio_player_title_wrap"> |
||||||
|
<div class="audio_player_meta pull-right" ng-if="audio.downloaded && (mediaPlayer.player.duration || audio.duration)" ng-switch="mediaPlayer.player.playing || mediaPlayer.player.currentTime > 0"> |
||||||
|
<span ng-switch-when="true" class="audio_player_duration" ng-bind="mediaPlayer.player.currentTime | durationRemains : (mediaPlayer.player.duration || audio.duration)"></span> |
||||||
|
<span ng-switch-default class="audio_player_duration" ng-bind="mediaPlayer.player.duration || audio.duration | duration"></span> |
||||||
|
</div> |
||||||
<a ng-click="download()" class="audio_player_title" ng-switch="::audio.file_name.length > 0"> |
<a ng-click="download()" class="audio_player_title" ng-switch="::audio.file_name.length > 0"> |
||||||
<span ng-switch-when="true" ng-bind="::audio.file_name"></span> |
<span ng-switch-when="true" ng-bind="::audio.file_name"></span> |
||||||
<span ng-switch-default my-i18n="message_attach_audio_message"></span> |
<span ng-switch-default my-i18n="message_attach_audio_message"></span> |
||||||
</a> |
</a> |
||||||
<div class="audio_player_meta" ng-switch="audio.progress.enabled ? 'progress' : (!mediaPlayer.player.duration && !audio.duration ? 'size' : '')"> |
<div class="audio_player_meta" ng-if="!audio.downloaded || !(mediaPlayer.player.duration || audio.duration)" ng-switch="audio.progress.enabled"> |
||||||
<span ng-switch-when="progress" class="audio_player_size" ng-bind="audio.progress | formatSizeProgress"></span> |
<span ng-switch-when="true" class="audio_player_size" ng-bind="audio.progress | formatSizeProgress"></span> |
||||||
<span ng-switch-when="size" class="audio_player_size" ng-bind="audio.size | formatSize"></span> |
<span ng-switch-default class="audio_player_size" ng-bind="audio.size | formatSize"></span> |
||||||
<span ng-switch-default class="audio_player_duration" ng-bind="(mediaPlayer.player.playing || mediaPlayer.player.currentTime > 0) ? mediaPlayer.player.currentTime : (mediaPlayer.player.duration || audio.duration) | duration"></span> |
|
||||||
</div> |
</div> |
||||||
</div> |
</div> |
||||||
<div class="audio_player_actions" ng-if="!audio.progress.enabled && !audio.url"> |
<div class="audio_player_actions" ng-if="!audio.progress.enabled && !audio.downloaded"> |
||||||
<a ng-click="togglePlay()" my-i18n="message_attach_audio_play"></a> |
|
||||||
<a ng-if="audio._ == 'document'" ng-click="download()" my-i18n="message_attach_document_download"></a> |
<a ng-if="audio._ == 'document'" ng-click="download()" my-i18n="message_attach_document_download"></a> |
||||||
|
<a ng-click="togglePlay()" my-i18n="message_attach_audio_play"></a> |
||||||
</div> |
</div> |
||||||
<div class="audio_player_progress_wrap" ng-if="audio.progress.enabled || audio.url" ng-switch="audio.progress.enabled"> |
<div class="audio_player_progress_wrap" ng-if="audio.progress.enabled || audio.downloaded" ng-switch="audio.progress.enabled"> |
||||||
<div ng-switch-when="true" class="progress tg_down_progress"> |
<div ng-switch-when="true" class="clearfix im_message_cancelable_progress_wrap"> |
||||||
<div class="progress-bar progress-bar-success" ng-style="{width: audio.progress.percent + '%'}"></div> |
<a class="im_message_media_progress_cancel pull-right" ng-click="audio.progress.cancel()" my-i18n="modal_cancel"></a> |
||||||
</div> |
<div class="im_message_download_progress_wrap"> |
||||||
<div ng-switch-default class="progress tg_play_progress"> |
<div class="progress tg_down_progress"> |
||||||
<div class="progress-bar progress-bar-success" ng-style="{width: mediaPlayer.player.currentTime / (mediaPlayer.player.duration || audio.duration) * 100 + '%'}"></div> |
<div class="progress-bar progress-bar-success" ng-style="{width: audio.progress.percent + '%'}"></div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div ng-switch-default class="im_message_playback_progress_wrap"> |
||||||
|
<div class="audio_player_seek_slider" my-slider slider-model="mediaPlayer.player.currentTime" slider-max="mediaPlayer.player.duration || audio.duration" slider-onchange="seek(value)"></div> |
||||||
</div> |
</div> |
||||||
</div> |
</div> |
||||||
<audio ng-if="audio.url" media-player="mediaPlayer.player"> |
<audio ng-if="audio.url" media-player="mediaPlayer.player"> |
||||||
<source ng-src="{{::audio.url}}" type="audio/ogg" /> |
<source ng-src="{{::audio.url}}" type="audio/ogg" volume="{{::volume}}" /> |
||||||
</audio> |
</audio> |
||||||
</div> |
</div> |
@ -0,0 +1,21 @@ |
|||||||
|
<div class="media_modal_wrap document_modal_wrap" my-modal-position> |
||||||
|
|
||||||
|
<div class="modal-body"> |
||||||
|
|
||||||
|
<div my-load-document="document"></div> |
||||||
|
|
||||||
|
<div class="media_meta_wrap clearfix"> |
||||||
|
<div class="media_modal_actions pull-right"> |
||||||
|
<a href="" class="media_modal_action_link" ng-click="download()" my-i18n="media_modal_download"></a> |
||||||
|
<a ng-if="messageID" href="" class="media_modal_action_link" ng-click="forward()" my-i18n="media_modal_forward"></a> |
||||||
|
<a ng-if="messageID" href="" class="media_modal_action_link" ng-click="delete()" my-i18n="media_modal_delete"></a> |
||||||
|
</div> |
||||||
|
|
||||||
|
<p class="media_modal_info"> |
||||||
|
<a class="media_modal_author" my-user-link="document.user_id"></a>, <span ng-bind="document.date | dateOrTime"></span> |
||||||
|
</p> |
||||||
|
</div> |
||||||
|
|
||||||
|
</div> |
||||||
|
|
||||||
|
</div> |
@ -0,0 +1,21 @@ |
|||||||
|
<div class="document_modal_image_wrap"> |
||||||
|
<div class="img_fullsize_with_progress_wrap document_fullsize_with_progress_wrap" ng-style="{width: frameWidth + 'px', height: frameHeight + 'px'}"> |
||||||
|
<div class="img_fullsize_progress_overlay"> |
||||||
|
<div class="img_fullsize_progress_wrap" ng-style="{width: frameWidth + 'px', height: frameHeight + 'px'}"> |
||||||
|
<div class="img_fullsize_progress progress tg_progress"> |
||||||
|
<div class="progress-bar progress-bar-success" style="width: {{document.progress.percent}}%"></div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="img_fullsize_wrap" ng-if="thumbSrc.length > 0"> |
||||||
|
<img |
||||||
|
class="img_fullsize" |
||||||
|
ng-src="{{thumbSrc}}" |
||||||
|
ng-style="{width: imageWidth + 'px', height: imageHeight + 'px'}" |
||||||
|
/> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="document_fullsize_wrap" ng-click="toggleZoom(!zoomed)"> |
||||||
|
<img class="document_fullsize_img" /> |
||||||
|
</div> |
||||||
|
</div> |
@ -1,3 +0,0 @@ |
|||||||
<div class="im_message_audio"> |
|
||||||
<div my-audio-player audio="historyMessage.media.audio"></div> |
|
||||||
</div> |
|
@ -0,0 +1,6 @@ |
|||||||
|
<div class="tg_slider_wrap"> |
||||||
|
<div class="tg_slider_thumb"></div> |
||||||
|
<div class="tg_slider_track"> |
||||||
|
<div class="tg_slider_track_fill"></div> |
||||||
|
</div> |
||||||
|
</div> |
@ -1,3 +0,0 @@ |
|||||||
<div class="im_message_audio"> |
|
||||||
<div my-audio-player audio="historyMessage.media.audio"></div> |
|
||||||
</div> |
|
@ -1,11 +1,11 @@ |
|||||||
<div class="im_message_video im_message_document_thumbed"> |
<div class="im_message_video im_message_document_thumbed"> |
||||||
<a class="im_message_video_thumb" href="" ng-click="openVideo(historyMessage.media.video.id, historyMessage.id)" ng-style="::{width: historyMessage.media.video.thumb.width + 'px'}"> |
<a class="im_message_video_thumb" href="" ng-click="videoOpen()" ng-style="::{width: video.thumb.width + 'px'}"> |
||||||
<span class="im_message_video_duration" ng-bind="::historyMessage.media.video.duration | duration"></span> |
<span class="im_message_video_duration" ng-bind="::video.duration | duration"></span> |
||||||
<i class="icon icon-videoplay"></i> |
<i class="icon icon-videoplay"></i> |
||||||
<img |
<img |
||||||
class="im_message_video_thumb" |
class="im_message_video_thumb" |
||||||
my-load-thumb |
my-load-thumb |
||||||
thumb="historyMessage.media.video.thumb" |
thumb="video.thumb" |
||||||
/> |
/> |
||||||
</a> |
</a> |
||||||
</div> |
</div> |
@ -0,0 +1,392 @@ |
|||||||
|
/* |
||||||
|
* Rusha, a JavaScript implementation of the Secure Hash Algorithm, SHA-1, |
||||||
|
* as defined in FIPS PUB 180-1, tuned for high performance with large inputs. |
||||||
|
* (http://github.com/srijs/rusha)
|
||||||
|
* |
||||||
|
* Inspired by Paul Johnstons implementation (http://pajhome.org.uk/crypt/md5).
|
||||||
|
* |
||||||
|
* Copyright (c) 2013 Sam Rijs (http://awesam.de).
|
||||||
|
* Released under the terms of the MIT license as follows: |
||||||
|
* |
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a |
||||||
|
* copy of this software and associated documentation files (the "Software"), |
||||||
|
* to deal in the Software without restriction, including without limitation |
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the |
||||||
|
* Software is furnished to do so, subject to the following conditions: |
||||||
|
* |
||||||
|
* The above copyright notice and this permission notice shall be included in |
||||||
|
* all copies or substantial portions of the Software. |
||||||
|
* |
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
||||||
|
* IN THE SOFTWARE. |
||||||
|
*/ |
||||||
|
(function (global) { |
||||||
|
// If we'e running in Node.JS, export a module.
|
||||||
|
if (typeof module !== 'undefined') { |
||||||
|
module.exports = Rusha; |
||||||
|
} |
||||||
|
// If we're running in a DOM context, export
|
||||||
|
// the Rusha object to toplevel.
|
||||||
|
if (typeof global !== 'undefined') { |
||||||
|
global.Rusha = Rusha; |
||||||
|
} |
||||||
|
// If we're running in a webworker, accept
|
||||||
|
// messages containing a jobid and a buffer
|
||||||
|
// or blob object, and return the hash result.
|
||||||
|
if (typeof FileReaderSync !== 'undefined') { |
||||||
|
var reader = new FileReaderSync(), hasher = new Rusha(4 * 1024 * 1024); |
||||||
|
self.onmessage = function onMessage(event) { |
||||||
|
var hash, data = event.data.data; |
||||||
|
if (data instanceof Blob) { |
||||||
|
try { |
||||||
|
data = reader.readAsBinaryString(data); |
||||||
|
} catch (e) { |
||||||
|
self.postMessage({ |
||||||
|
id: event.data.id, |
||||||
|
error: e.name |
||||||
|
}); |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
hash = hasher.digest(data); |
||||||
|
self.postMessage({ |
||||||
|
id: event.data.id, |
||||||
|
hash: hash |
||||||
|
}); |
||||||
|
}; |
||||||
|
} |
||||||
|
var util = { |
||||||
|
getDataType: function (data) { |
||||||
|
if (typeof data === 'string') { |
||||||
|
return 'string'; |
||||||
|
} |
||||||
|
if (data instanceof Array) { |
||||||
|
return 'array'; |
||||||
|
} |
||||||
|
if (typeof global !== 'undefined' && global.Buffer && global.Buffer.isBuffer(data)) { |
||||||
|
return 'buffer'; |
||||||
|
} |
||||||
|
if (data instanceof ArrayBuffer) { |
||||||
|
return 'arraybuffer'; |
||||||
|
} |
||||||
|
if (data.buffer instanceof ArrayBuffer) { |
||||||
|
return 'view'; |
||||||
|
} |
||||||
|
throw new Error('Unsupported data type.'); |
||||||
|
} |
||||||
|
}; |
||||||
|
// The Rusha object is a wrapper around the low-level RushaCore.
|
||||||
|
// It provides means of converting different inputs to the
|
||||||
|
// format accepted by RushaCore as well as other utility methods.
|
||||||
|
function Rusha(chunkSize) { |
||||||
|
'use strict'; |
||||||
|
// Private object structure.
|
||||||
|
var self$2 = { fill: 0 }; |
||||||
|
// Calculate the length of buffer that the sha1 routine uses
|
||||||
|
// including the padding.
|
||||||
|
var padlen = function (len) { |
||||||
|
for (len += 9; len % 64 > 0; len += 1); |
||||||
|
return len; |
||||||
|
}; |
||||||
|
var padZeroes = function (bin, len) { |
||||||
|
for (var i = len >> 2; i < bin.length; i++) |
||||||
|
bin[i] = 0; |
||||||
|
}; |
||||||
|
var padData = function (bin, chunkLen, msgLen) { |
||||||
|
bin[chunkLen >> 2] |= 128 << 24 - (chunkLen % 4 << 3); |
||||||
|
bin[((chunkLen >> 2) + 2 & ~15) + 15] = msgLen << 3; |
||||||
|
}; |
||||||
|
// Convert a binary string and write it to the heap.
|
||||||
|
// A binary string is expected to only contain char codes < 256.
|
||||||
|
var convStr = function (H8, H32, start, len, off) { |
||||||
|
var str = this, i, om = off % 4, lm = len % 4, j = len - lm; |
||||||
|
if (j > 0) { |
||||||
|
switch (om) { |
||||||
|
case 0: |
||||||
|
H8[off + 3 | 0] = str.charCodeAt(start); |
||||||
|
case 1: |
||||||
|
H8[off + 2 | 0] = str.charCodeAt(start + 1); |
||||||
|
case 2: |
||||||
|
H8[off + 1 | 0] = str.charCodeAt(start + 2); |
||||||
|
case 3: |
||||||
|
H8[off | 0] = str.charCodeAt(start + 3); |
||||||
|
} |
||||||
|
} |
||||||
|
for (i = om; i < j; i = i + 4 | 0) { |
||||||
|
H32[off + i >> 2] = str.charCodeAt(start + i) << 24 | str.charCodeAt(start + i + 1) << 16 | str.charCodeAt(start + i + 2) << 8 | str.charCodeAt(start + i + 3); |
||||||
|
} |
||||||
|
switch (lm) { |
||||||
|
case 3: |
||||||
|
H8[off + j + 1 | 0] = str.charCodeAt(start + j + 2); |
||||||
|
case 2: |
||||||
|
H8[off + j + 2 | 0] = str.charCodeAt(start + j + 1); |
||||||
|
case 1: |
||||||
|
H8[off + j + 3 | 0] = str.charCodeAt(start + j); |
||||||
|
} |
||||||
|
}; |
||||||
|
// Convert a buffer or array and write it to the heap.
|
||||||
|
// The buffer or array is expected to only contain elements < 256.
|
||||||
|
var convBuf = function (H8, H32, start, len, off) { |
||||||
|
var buf = this, i, om = off % 4, lm = len % 4, j = len - lm; |
||||||
|
if (j > 0) { |
||||||
|
switch (om) { |
||||||
|
case 0: |
||||||
|
H8[off + 3 | 0] = buf[start]; |
||||||
|
case 1: |
||||||
|
H8[off + 2 | 0] = buf[start + 1]; |
||||||
|
case 2: |
||||||
|
H8[off + 1 | 0] = buf[start + 2]; |
||||||
|
case 3: |
||||||
|
H8[off | 0] = buf[start + 3]; |
||||||
|
} |
||||||
|
} |
||||||
|
for (i = 4 - om; i < j; i = i += 4 | 0) { |
||||||
|
H32[off + i >> 2] = buf[start + i] << 24 | buf[start + i + 1] << 16 | buf[start + i + 2] << 8 | buf[start + i + 3]; |
||||||
|
} |
||||||
|
switch (lm) { |
||||||
|
case 3: |
||||||
|
H8[off + j + 1 | 0] = buf[start + j + 2]; |
||||||
|
case 2: |
||||||
|
H8[off + j + 2 | 0] = buf[start + j + 1]; |
||||||
|
case 1: |
||||||
|
H8[off + j + 3 | 0] = buf[start + j]; |
||||||
|
} |
||||||
|
}; |
||||||
|
var convFn = function (data) { |
||||||
|
switch (util.getDataType(data)) { |
||||||
|
case 'string': |
||||||
|
return convStr.bind(data); |
||||||
|
case 'array': |
||||||
|
return convBuf.bind(data); |
||||||
|
case 'buffer': |
||||||
|
return convBuf.bind(data); |
||||||
|
case 'arraybuffer': |
||||||
|
return convBuf.bind(new Uint8Array(data)); |
||||||
|
case 'view': |
||||||
|
return convBuf.bind(new Uint8Array(data.buffer)); |
||||||
|
} |
||||||
|
}; |
||||||
|
var slice = function (data, offset) { |
||||||
|
switch (util.getDataType(data)) { |
||||||
|
case 'string': |
||||||
|
return data.slice(offset); |
||||||
|
case 'array': |
||||||
|
return data.slice(offset); |
||||||
|
case 'buffer': |
||||||
|
return data.slice(offset); |
||||||
|
case 'arraybuffer': |
||||||
|
return data.slice(offset); |
||||||
|
case 'view': |
||||||
|
return data.buffer.slice(offset); |
||||||
|
} |
||||||
|
}; |
||||||
|
// Convert an ArrayBuffer into its hexadecimal string representation.
|
||||||
|
var hex = function (arrayBuffer) { |
||||||
|
var i, x, hex_tab = '0123456789abcdef', res = [], binarray = new Uint8Array(arrayBuffer); |
||||||
|
for (i = 0; i < binarray.length; i++) { |
||||||
|
x = binarray[i]; |
||||||
|
res[i] = hex_tab.charAt(x >> 4 & 15) + hex_tab.charAt(x >> 0 & 15); |
||||||
|
} |
||||||
|
return res.join(''); |
||||||
|
}; |
||||||
|
var ceilHeapSize = function (v) { |
||||||
|
// The asm.js spec says:
|
||||||
|
// The heap object's byteLength must be either
|
||||||
|
// 2^n for n in [12, 24) or 2^24 * n for n ≥ 1.
|
||||||
|
// Also, byteLengths smaller than 2^16 are deprecated.
|
||||||
|
var p; |
||||||
|
// If v is smaller than 2^16, the smallest possible solution
|
||||||
|
// is 2^16.
|
||||||
|
if (v <= 65536) |
||||||
|
return 65536; |
||||||
|
// If v < 2^24, we round up to 2^n,
|
||||||
|
// otherwise we round up to 2^24 * n.
|
||||||
|
if (v < 16777216) { |
||||||
|
for (p = 1; p < v; p = p << 1); |
||||||
|
} else { |
||||||
|
for (p = 16777216; p < v; p += 16777216); |
||||||
|
} |
||||||
|
return p; |
||||||
|
}; |
||||||
|
// Initialize the internal data structures to a new capacity.
|
||||||
|
var init = function (size) { |
||||||
|
if (size % 64 > 0) { |
||||||
|
throw new Error('Chunk size must be a multiple of 128 bit'); |
||||||
|
} |
||||||
|
self$2.maxChunkLen = size; |
||||||
|
self$2.padMaxChunkLen = padlen(size); |
||||||
|
// The size of the heap is the sum of:
|
||||||
|
// 1. The padded input message size
|
||||||
|
// 2. The extended space the algorithm needs (320 byte)
|
||||||
|
// 3. The 160 bit state the algoritm uses
|
||||||
|
self$2.heap = new ArrayBuffer(ceilHeapSize(self$2.padMaxChunkLen + 320 + 20)); |
||||||
|
self$2.h32 = new Int32Array(self$2.heap); |
||||||
|
self$2.h8 = new Int8Array(self$2.heap); |
||||||
|
self$2.core = RushaCore({ |
||||||
|
Int32Array: Int32Array, |
||||||
|
DataView: DataView |
||||||
|
}, {}, self$2.heap); |
||||||
|
self$2.buffer = null; |
||||||
|
}; |
||||||
|
// Iinitializethe datastructures according
|
||||||
|
// to a chunk siyze.
|
||||||
|
init(chunkSize || 64 * 1024); |
||||||
|
var initState = function (heap, padMsgLen) { |
||||||
|
var io = new Int32Array(heap, padMsgLen + 320, 5); |
||||||
|
io[0] = 1732584193; |
||||||
|
io[1] = -271733879; |
||||||
|
io[2] = -1732584194; |
||||||
|
io[3] = 271733878; |
||||||
|
io[4] = -1009589776; |
||||||
|
}; |
||||||
|
var padChunk = function (chunkLen, msgLen) { |
||||||
|
var padChunkLen = padlen(chunkLen); |
||||||
|
var view = new Int32Array(self$2.heap, 0, padChunkLen >> 2); |
||||||
|
padZeroes(view, chunkLen); |
||||||
|
padData(view, chunkLen, msgLen); |
||||||
|
return padChunkLen; |
||||||
|
}; |
||||||
|
// Write data to the heap.
|
||||||
|
var write = function (data, chunkOffset, chunkLen) { |
||||||
|
convFn(data)(self$2.h8, self$2.h32, chunkOffset, chunkLen, 0); |
||||||
|
}; |
||||||
|
// Initialize and call the RushaCore,
|
||||||
|
// assuming an input buffer of length len * 4.
|
||||||
|
var coreCall = function (data, chunkOffset, chunkLen, msgLen, finalize) { |
||||||
|
var padChunkLen = chunkLen; |
||||||
|
if (finalize) { |
||||||
|
padChunkLen = padChunk(chunkLen, msgLen); |
||||||
|
} |
||||||
|
write(data, chunkOffset, chunkLen); |
||||||
|
self$2.core.hash(padChunkLen, self$2.padMaxChunkLen); |
||||||
|
}; |
||||||
|
var getRawDigest = function (heap, padMaxChunkLen) { |
||||||
|
var io = new Int32Array(heap, padMaxChunkLen + 320, 5); |
||||||
|
var out = new Int32Array(5); |
||||||
|
var arr = new DataView(out.buffer); |
||||||
|
arr.setInt32(0, io[0], false); |
||||||
|
arr.setInt32(4, io[1], false); |
||||||
|
arr.setInt32(8, io[2], false); |
||||||
|
arr.setInt32(12, io[3], false); |
||||||
|
arr.setInt32(16, io[4], false); |
||||||
|
return out; |
||||||
|
}; |
||||||
|
// Calculate the hash digest as an array of 5 32bit integers.
|
||||||
|
var rawDigest = this.rawDigest = function (str) { |
||||||
|
var msgLen = str.byteLength || str.length; |
||||||
|
initState(self$2.heap, self$2.padMaxChunkLen); |
||||||
|
var chunkOffset = 0, chunkLen = self$2.maxChunkLen, last; |
||||||
|
for (chunkOffset = 0; msgLen > chunkOffset + chunkLen; chunkOffset += chunkLen) { |
||||||
|
coreCall(str, chunkOffset, chunkLen, msgLen, false); |
||||||
|
} |
||||||
|
coreCall(str, chunkOffset, msgLen - chunkOffset, msgLen, true); |
||||||
|
return getRawDigest(self$2.heap, self$2.padMaxChunkLen); |
||||||
|
}; |
||||||
|
// The digest and digestFrom* interface returns the hash digest
|
||||||
|
// as a hex string.
|
||||||
|
this.digest = this.digestFromString = this.digestFromBuffer = this.digestFromArrayBuffer = function (str) { |
||||||
|
return hex(rawDigest(str).buffer); |
||||||
|
}; |
||||||
|
} |
||||||
|
; |
||||||
|
// The low-level RushCore module provides the heart of Rusha,
|
||||||
|
// a high-speed sha1 implementation working on an Int32Array heap.
|
||||||
|
// At first glance, the implementation seems complicated, however
|
||||||
|
// with the SHA1 spec at hand, it is obvious this almost a textbook
|
||||||
|
// implementation that has a few functions hand-inlined and a few loops
|
||||||
|
// hand-unrolled.
|
||||||
|
function RushaCore(stdlib, foreign, heap) { |
||||||
|
'use asm'; |
||||||
|
var H = new stdlib.Int32Array(heap); |
||||||
|
function hash(k, x) { |
||||||
|
// k in bytes
|
||||||
|
k = k | 0; |
||||||
|
x = x | 0; |
||||||
|
var i = 0, j = 0, y0 = 0, z0 = 0, y1 = 0, z1 = 0, y2 = 0, z2 = 0, y3 = 0, z3 = 0, y4 = 0, z4 = 0, t0 = 0, t1 = 0; |
||||||
|
y0 = H[x + 320 >> 2] | 0; |
||||||
|
y1 = H[x + 324 >> 2] | 0; |
||||||
|
y2 = H[x + 328 >> 2] | 0; |
||||||
|
y3 = H[x + 332 >> 2] | 0; |
||||||
|
y4 = H[x + 336 >> 2] | 0; |
||||||
|
for (i = 0; (i | 0) < (k | 0); i = i + 64 | 0) { |
||||||
|
z0 = y0; |
||||||
|
z1 = y1; |
||||||
|
z2 = y2; |
||||||
|
z3 = y3; |
||||||
|
z4 = y4; |
||||||
|
for (j = 0; (j | 0) < 64; j = j + 4 | 0) { |
||||||
|
t1 = H[i + j >> 2] | 0; |
||||||
|
t0 = ((y0 << 5 | y0 >>> 27) + (y1 & y2 | ~y1 & y3) | 0) + ((t1 + y4 | 0) + 1518500249 | 0) | 0; |
||||||
|
y4 = y3; |
||||||
|
y3 = y2; |
||||||
|
y2 = y1 << 30 | y1 >>> 2; |
||||||
|
y1 = y0; |
||||||
|
y0 = t0; |
||||||
|
; |
||||||
|
H[k + j >> 2] = t1; |
||||||
|
} |
||||||
|
for (j = k + 64 | 0; (j | 0) < (k + 80 | 0); j = j + 4 | 0) { |
||||||
|
t1 = (H[j - 12 >> 2] ^ H[j - 32 >> 2] ^ H[j - 56 >> 2] ^ H[j - 64 >> 2]) << 1 | (H[j - 12 >> 2] ^ H[j - 32 >> 2] ^ H[j - 56 >> 2] ^ H[j - 64 >> 2]) >>> 31; |
||||||
|
t0 = ((y0 << 5 | y0 >>> 27) + (y1 & y2 | ~y1 & y3) | 0) + ((t1 + y4 | 0) + 1518500249 | 0) | 0; |
||||||
|
y4 = y3; |
||||||
|
y3 = y2; |
||||||
|
y2 = y1 << 30 | y1 >>> 2; |
||||||
|
y1 = y0; |
||||||
|
y0 = t0; |
||||||
|
; |
||||||
|
H[j >> 2] = t1; |
||||||
|
} |
||||||
|
for (j = k + 80 | 0; (j | 0) < (k + 160 | 0); j = j + 4 | 0) { |
||||||
|
t1 = (H[j - 12 >> 2] ^ H[j - 32 >> 2] ^ H[j - 56 >> 2] ^ H[j - 64 >> 2]) << 1 | (H[j - 12 >> 2] ^ H[j - 32 >> 2] ^ H[j - 56 >> 2] ^ H[j - 64 >> 2]) >>> 31; |
||||||
|
t0 = ((y0 << 5 | y0 >>> 27) + (y1 ^ y2 ^ y3) | 0) + ((t1 + y4 | 0) + 1859775393 | 0) | 0; |
||||||
|
y4 = y3; |
||||||
|
y3 = y2; |
||||||
|
y2 = y1 << 30 | y1 >>> 2; |
||||||
|
y1 = y0; |
||||||
|
y0 = t0; |
||||||
|
; |
||||||
|
H[j >> 2] = t1; |
||||||
|
} |
||||||
|
for (j = k + 160 | 0; (j | 0) < (k + 240 | 0); j = j + 4 | 0) { |
||||||
|
t1 = (H[j - 12 >> 2] ^ H[j - 32 >> 2] ^ H[j - 56 >> 2] ^ H[j - 64 >> 2]) << 1 | (H[j - 12 >> 2] ^ H[j - 32 >> 2] ^ H[j - 56 >> 2] ^ H[j - 64 >> 2]) >>> 31; |
||||||
|
t0 = ((y0 << 5 | y0 >>> 27) + (y1 & y2 | y1 & y3 | y2 & y3) | 0) + ((t1 + y4 | 0) - 1894007588 | 0) | 0; |
||||||
|
y4 = y3; |
||||||
|
y3 = y2; |
||||||
|
y2 = y1 << 30 | y1 >>> 2; |
||||||
|
y1 = y0; |
||||||
|
y0 = t0; |
||||||
|
; |
||||||
|
H[j >> 2] = t1; |
||||||
|
} |
||||||
|
for (j = k + 240 | 0; (j | 0) < (k + 320 | 0); j = j + 4 | 0) { |
||||||
|
t1 = (H[j - 12 >> 2] ^ H[j - 32 >> 2] ^ H[j - 56 >> 2] ^ H[j - 64 >> 2]) << 1 | (H[j - 12 >> 2] ^ H[j - 32 >> 2] ^ H[j - 56 >> 2] ^ H[j - 64 >> 2]) >>> 31; |
||||||
|
t0 = ((y0 << 5 | y0 >>> 27) + (y1 ^ y2 ^ y3) | 0) + ((t1 + y4 | 0) - 899497514 | 0) | 0; |
||||||
|
y4 = y3; |
||||||
|
y3 = y2; |
||||||
|
y2 = y1 << 30 | y1 >>> 2; |
||||||
|
y1 = y0; |
||||||
|
y0 = t0; |
||||||
|
; |
||||||
|
H[j >> 2] = t1; |
||||||
|
} |
||||||
|
y0 = y0 + z0 | 0; |
||||||
|
y1 = y1 + z1 | 0; |
||||||
|
y2 = y2 + z2 | 0; |
||||||
|
y3 = y3 + z3 | 0; |
||||||
|
y4 = y4 + z4 | 0; |
||||||
|
} |
||||||
|
H[x + 320 >> 2] = y0; |
||||||
|
H[x + 324 >> 2] = y1; |
||||||
|
H[x + 328 >> 2] = y2; |
||||||
|
H[x + 332 >> 2] = y3; |
||||||
|
H[x + 336 >> 2] = y4; |
||||||
|
} |
||||||
|
return { hash: hash }; |
||||||
|
} |
||||||
|
}(this)); |
@ -1,6 +1,6 @@ |
|||||||
CACHE MANIFEST |
CACHE MANIFEST |
||||||
|
|
||||||
# 39 |
# 41 |
||||||
|
|
||||||
NETWORK: |
NETWORK: |
||||||
* |
* |
||||||
|
Loading…
Reference in new issue