Add Curve25519
This commit is contained in:
parent
70bfb54e55
commit
81343bc06f
@ -21,6 +21,7 @@ SET (star_core_HEADERS
|
||||
StarColor.hpp
|
||||
StarCompression.hpp
|
||||
StarConfig.hpp
|
||||
StarCurve25519.hpp
|
||||
StarDataStream.hpp
|
||||
StarDataStreamDevices.hpp
|
||||
StarDataStreamExtra.hpp
|
||||
@ -133,6 +134,7 @@ SET (star_core_SOURCES
|
||||
StarByteArray.cpp
|
||||
StarColor.cpp
|
||||
StarCompression.cpp
|
||||
StarCurve25519.cpp
|
||||
StarDataStream.cpp
|
||||
StarDataStreamDevices.cpp
|
||||
StarDirectives.cpp
|
||||
|
50
source/core/StarCurve25519.cpp
Normal file
50
source/core/StarCurve25519.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
#include "StarCurve25519.hpp"
|
||||
#include "StarRandom.hpp"
|
||||
#include "StarLogging.hpp"
|
||||
|
||||
#include "curve25519/include/curve25519_dh.h"
|
||||
#include "curve25519/include/ed25519_signature.h"
|
||||
|
||||
namespace Star::Curve25519 {
|
||||
|
||||
struct KeySet {
|
||||
PrivateKey privateKey;
|
||||
PublicKey publicKey;
|
||||
|
||||
KeySet() {
|
||||
SecretKey secret;
|
||||
Random::randBytes(SecretKeySize).copyTo((char*)secret.data());
|
||||
|
||||
secret[0] &= 248;
|
||||
secret[31] &= 127;
|
||||
secret[31] |= 64;
|
||||
|
||||
ed25519_CreateKeyPair(privateKey.data(), publicKey.data(), nullptr, secret.data());
|
||||
|
||||
Logger::info("Generated Curve25519 key-pair");
|
||||
}
|
||||
};
|
||||
|
||||
static KeySet const& staticKeys() {
|
||||
static KeySet keys;
|
||||
|
||||
return keys;
|
||||
}
|
||||
|
||||
PrivateKey const& privateKey() { return staticKeys().privateKey; }
|
||||
|
||||
|
||||
|
||||
Signature sign(void* data, size_t len) {
|
||||
Signature signature;
|
||||
ed25519_SignMessage(signature.data(), privateKey().data(), nullptr, (unsigned char*)data, len);
|
||||
return signature;
|
||||
}
|
||||
|
||||
bool verify(uint8_t const* signature, uint8_t const* publicKey, void* data, size_t len) {
|
||||
return ed25519_VerifySignature(signature, publicKey, (unsigned char*)data, len);
|
||||
}
|
||||
|
||||
PublicKey const& publicKey() { return staticKeys().publicKey; }
|
||||
|
||||
}
|
25
source/core/StarCurve25519.hpp
Normal file
25
source/core/StarCurve25519.hpp
Normal file
@ -0,0 +1,25 @@
|
||||
#ifndef STAR_CURVE_25519_HPP
|
||||
#define STAR_CURVE_25519_HPP
|
||||
#include "StarEncode.hpp"
|
||||
#include "StarByteArray.hpp"
|
||||
#include "StarArray.hpp"
|
||||
|
||||
namespace Star::Curve25519 {
|
||||
|
||||
constexpr size_t PublicKeySize = 32;
|
||||
constexpr size_t SecretKeySize = 32;
|
||||
constexpr size_t PrivateKeySize = 64;
|
||||
constexpr size_t SignatureSize = 64;
|
||||
|
||||
typedef Array<uint8_t, PublicKeySize> PublicKey;
|
||||
typedef Array<uint8_t, SecretKeySize> SecretKey;
|
||||
typedef Array<uint8_t, PrivateKeySize> PrivateKey;
|
||||
typedef Array<uint8_t, SignatureSize> Signature;
|
||||
|
||||
PublicKey const& publicKey();
|
||||
Signature sign(void* data, size_t len);
|
||||
bool verify(uint8_t const* signature, uint8_t const* publicKey, void* data, size_t len);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
14
source/extern/CMakeLists.txt
vendored
14
source/extern/CMakeLists.txt
vendored
@ -3,17 +3,19 @@ SET (OPUS_INSTALL_CMAKE_CONFIG_MODULE OFF)
|
||||
SET (OPUS_X86_MAY_HAVE_AVX OFF)
|
||||
SET (OPUS_X86_MAY_HAVE_SSE4_1 OFF)
|
||||
SET (OPUS_STACK_PROTECTOR OFF)
|
||||
|
||||
ADD_SUBDIRECTORY (opus)
|
||||
|
||||
INCLUDE_DIRECTORIES (
|
||||
${STAR_EXTERN_INCLUDES}
|
||||
opus
|
||||
opus/include
|
||||
fmt
|
||||
lua
|
||||
)
|
||||
|
||||
SET (star_extern_HEADERS
|
||||
curve25519/include/curve25519_dh.h
|
||||
curve25519/include/ed25519_signature.h
|
||||
curve25519/include/external_calls.h
|
||||
fmt/core.h
|
||||
fmt/format.h
|
||||
fmt/format-inl.h
|
||||
@ -31,6 +33,14 @@ SET (star_extern_HEADERS
|
||||
)
|
||||
|
||||
SET (star_extern_SOURCES
|
||||
curve25519/source/sha512.c
|
||||
curve25519/source/curve25519_dh.c
|
||||
curve25519/source/curve25519_mehdi.c
|
||||
curve25519/source/curve25519_order.c
|
||||
curve25519/source/curve25519_utils.c
|
||||
curve25519/source/custom_blind.c
|
||||
curve25519/source/ed25519_sign.c
|
||||
curve25519/source/ed25519_verify.c
|
||||
xxhash.c
|
||||
fmt/format.cc
|
||||
lua/lapi.c
|
||||
|
53
source/extern/curve25519/include/curve25519_dh.h
vendored
Normal file
53
source/extern/curve25519/include/curve25519_dh.h
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
/* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 mehdi sotoodeh
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __curve25519_dh_key_exchange_h__
|
||||
#define __curve25519_dh_key_exchange_h__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Return public key associated with sk */
|
||||
/* sk will be trimmed on return */
|
||||
void curve25519_dh_CalculatePublicKey(
|
||||
unsigned char *pk, /* [32-bytes] OUT: Public key */
|
||||
unsigned char *sk); /* [32-bytes] IN/OUT: Your secret key */
|
||||
|
||||
/* Faster alternative for curve25519_dh_CalculatePublicKey */
|
||||
/* sk will be trimmed on return */
|
||||
void curve25519_dh_CalculatePublicKey_fast(
|
||||
unsigned char *pk, /* [32-bytes] OUT: Public key */
|
||||
unsigned char *sk); /* [32-bytes] IN/OUT: Your secret key */
|
||||
|
||||
/* sk will be trimmed on return */
|
||||
void curve25519_dh_CreateSharedKey(
|
||||
unsigned char *shared, /* [32-bytes] OUT: Created shared key */
|
||||
const unsigned char *pk, /* [32-bytes] IN: Other side's public key */
|
||||
unsigned char *sk); /* [32-bytes] IN/OUT: Your secret key */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __curve25519_dh_key_exchange_h__ */
|
98
source/extern/curve25519/include/ed25519_signature.h
vendored
Normal file
98
source/extern/curve25519/include/ed25519_signature.h
vendored
Normal file
@ -0,0 +1,98 @@
|
||||
/* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 mehdi sotoodeh
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __ed25519_signature_h__
|
||||
#define __ed25519_signature_h__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* -- ed25519-sign ------------------------------------------------------------- */
|
||||
|
||||
#define ed25519_public_key_size 32
|
||||
#define ed25519_secret_key_size 32
|
||||
#define ed25519_private_key_size 64
|
||||
#define ed25519_signature_size 64
|
||||
|
||||
/* Generate public key associated with the secret key */
|
||||
void ed25519_CreateKeyPair(
|
||||
unsigned char *pubKey, /* OUT: public key */
|
||||
unsigned char *privKey, /* OUT: private key */
|
||||
const void *blinding, /* IN: [optional] null or blinding context */
|
||||
const unsigned char *sk); /* IN: secret key (32 bytes) */
|
||||
|
||||
/* Generate message signature */
|
||||
void ed25519_SignMessage(
|
||||
unsigned char *signature, /* OUT:[64 bytes] signature (R,S) */
|
||||
const unsigned char *privKey, /* IN: [64 bytes] private key (sk,pk) */
|
||||
const void *blinding, /* IN: [optional] null or blinding context */
|
||||
const unsigned char *msg, /* IN: [msg_size bytes] message to sign */
|
||||
size_t msg_size); /* IN: size of message */
|
||||
|
||||
void *ed25519_Blinding_Init(
|
||||
void *context, /* IO: null or ptr blinding context */
|
||||
const unsigned char *seed, /* IN: [size bytes] random blinding seed */
|
||||
size_t size); /* IN: size of blinding seed */
|
||||
|
||||
void ed25519_Blinding_Finish(
|
||||
void *context); /* IN: blinding context */
|
||||
|
||||
/* -- ed25519-verify ----------------------------------------------------------- */
|
||||
|
||||
/* Single-phased signature validation.
|
||||
Returns 1 for SUCCESS and 0 for FAILURE
|
||||
*/
|
||||
int ed25519_VerifySignature(
|
||||
const unsigned char *signature, /* IN: [64 bytes] signature (R,S) */
|
||||
const unsigned char *publicKey, /* IN: [32 bytes] public key */
|
||||
const unsigned char *msg, /* IN: [msg_size bytes] message to sign */
|
||||
size_t msg_size); /* IN: size of message */
|
||||
|
||||
/* First part of two-phase signature validation.
|
||||
This function creates context specifc to a given public key.
|
||||
Needs to be called once per public key
|
||||
*/
|
||||
void * ed25519_Verify_Init(
|
||||
void *context, /* IO: null or verify context to use */
|
||||
const unsigned char *publicKey); /* IN: [32 bytes] public key */
|
||||
|
||||
/* Second part of two-phase signature validation.
|
||||
Input context is output of ed25519_Verify_Init() for associated public key.
|
||||
Call it once for each message/signature pairs
|
||||
Returns 1 for SUCCESS and 0 for FAILURE
|
||||
*/
|
||||
int ed25519_Verify_Check(
|
||||
const void *context, /* IN: created by ed25519_Verify_Init */
|
||||
const unsigned char *signature, /* IN: signature (R,S) */
|
||||
const unsigned char *msg, /* IN: message to sign */
|
||||
size_t msg_size); /* IN: size of message */
|
||||
|
||||
/* Free up context memory */
|
||||
void ed25519_Verify_Finish(void *ctx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __ed25519_signature_h__ */
|
36
source/extern/curve25519/include/external_calls.h
vendored
Normal file
36
source/extern/curve25519/include/external_calls.h
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
/* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 mehdi sotoodeh
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __external_calls_h__
|
||||
#define __external_calls_h__
|
||||
|
||||
#include <memory.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define mem_alloc(size) malloc(size)
|
||||
#define mem_free(addr) free(addr)
|
||||
#define mem_clear(addr,size) memset(addr,0,size)
|
||||
#define mem_fill(addr,data,size) memset(addr,data,size)
|
||||
|
||||
#endif /* __external_calls_h__ */
|
121
source/extern/curve25519/source/BaseTypes.h
vendored
Normal file
121
source/extern/curve25519/source/BaseTypes.h
vendored
Normal file
@ -0,0 +1,121 @@
|
||||
/* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 mehdi sotoodeh
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __curve25519_base_type_h__
|
||||
#define __curve25519_base_type_h__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* Little-endian as default */
|
||||
#ifndef ECP_CONFIG_BIG_ENDIAN
|
||||
#define ECP_CONFIG_LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
typedef unsigned char U8;
|
||||
typedef signed char S8;
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
typedef unsigned __int16 U16;
|
||||
typedef signed __int16 S16;
|
||||
typedef unsigned __int32 U32;
|
||||
typedef signed __int32 S32;
|
||||
typedef unsigned __int64 U64;
|
||||
typedef signed __int64 S64;
|
||||
#else
|
||||
typedef uint16_t U16;
|
||||
typedef int16_t S16;
|
||||
typedef uint32_t U32;
|
||||
typedef int32_t S32;
|
||||
typedef uint64_t U64;
|
||||
typedef int64_t S64;
|
||||
#endif
|
||||
|
||||
typedef unsigned int SZ;
|
||||
|
||||
#ifdef ECP_CONFIG_BIG_ENDIAN
|
||||
typedef union
|
||||
{
|
||||
U16 u16;
|
||||
S16 s16;
|
||||
U8 bytes[2];
|
||||
struct { U8 b1, b0; } u8;
|
||||
struct { S8 b1; U8 b0; } s8;
|
||||
} M16;
|
||||
typedef union
|
||||
{
|
||||
U32 u32;
|
||||
S32 s32;
|
||||
U8 bytes[4];
|
||||
struct { U16 w1, w0; } u16;
|
||||
struct { S16 w1; U16 w0; } s16;
|
||||
struct { U8 b3, b2, b1, b0; } u8;
|
||||
struct { M16 hi, lo; } m16;
|
||||
} M32;
|
||||
typedef union
|
||||
{
|
||||
U64 u64;
|
||||
S64 s64;
|
||||
U8 bytes[8];
|
||||
struct { U32 hi, lo; } u32;
|
||||
struct { S32 hi; U32 lo; } s32;
|
||||
struct { U16 w3, w2, w1, w0; } u16;
|
||||
struct { U8 b7, b6, b5, b4, b3, b2, b1, b0; } u8;
|
||||
struct { M32 hi, lo; } m32;
|
||||
} M64;
|
||||
#else
|
||||
typedef union
|
||||
{
|
||||
U16 u16;
|
||||
S16 s16;
|
||||
U8 bytes[2];
|
||||
struct { U8 b0, b1; } u8;
|
||||
struct { U8 b0; S8 b1; } s8;
|
||||
} M16;
|
||||
typedef union
|
||||
{
|
||||
U32 u32;
|
||||
S32 s32;
|
||||
U8 bytes[4];
|
||||
struct { U16 w0, w1; } u16;
|
||||
struct { U16 w0; S16 w1; } s16;
|
||||
struct { U8 b0, b1, b2, b3; } u8;
|
||||
struct { M16 lo, hi; } m16;
|
||||
} M32;
|
||||
typedef union
|
||||
{
|
||||
U64 u64;
|
||||
S64 s64;
|
||||
U8 bytes[8];
|
||||
struct { U32 lo, hi; } u32;
|
||||
struct { U32 lo; S32 hi; } s32;
|
||||
struct { U16 w0, w1, w2, w3; } u16;
|
||||
struct { U8 b0, b1, b2, b3, b4, b5, b6, b7; } u8;
|
||||
struct { M32 lo, hi; } m32;
|
||||
} M64;
|
||||
#endif
|
||||
|
||||
#define IN
|
||||
#define OUT
|
||||
|
||||
#endif
|
1288
source/extern/curve25519/source/base_folding8.h
vendored
Normal file
1288
source/extern/curve25519/source/base_folding8.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
208
source/extern/curve25519/source/curve25519_dh.c
vendored
Normal file
208
source/extern/curve25519/source/curve25519_dh.c
vendored
Normal file
@ -0,0 +1,208 @@
|
||||
/* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 mehdi sotoodeh
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#include "../include/external_calls.h"
|
||||
#include "curve25519_mehdi.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
U_WORD X[K_WORDS]; /* x = X/Z */
|
||||
U_WORD Z[K_WORDS]; /* */
|
||||
} XZ_POINT;
|
||||
|
||||
extern const U_WORD _w_P[K_WORDS];
|
||||
extern EDP_BLINDING_CTX edp_custom_blinding;
|
||||
|
||||
/* x coordinate of base point */
|
||||
const U8 ecp_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 };
|
||||
/* Y = X + X */
|
||||
void ecp_MontDouble(XZ_POINT *Y, const XZ_POINT *X)
|
||||
{
|
||||
U_WORD A[K_WORDS], B[K_WORDS];
|
||||
/* x2 = (x+z)^2 * (x-z)^2 */
|
||||
/* z2 = ((x+z)^2 - (x-z)^2)*((x+z)^2 + ((A-2)/4)((x+z)^2 - (x-z)^2)) */
|
||||
ecp_AddReduce(A, X->X, X->Z); /* A = (x+z) */
|
||||
ecp_SubReduce(B, X->X, X->Z); /* B = (x-z) */
|
||||
ecp_SqrReduce(A, A); /* A = (x+z)^2 */
|
||||
ecp_SqrReduce(B, B); /* B = (x-z)^2 */
|
||||
ecp_MulReduce(Y->X, A, B); /* x2 = (x+z)^2 * (x-z)^2 */
|
||||
ecp_SubReduce(B, A, B); /* B = (x+z)^2 - (x-z)^2 */
|
||||
/* (486662-2)/4 = 121665 */
|
||||
ecp_WordMulAddReduce(A, A, 121665, B);
|
||||
ecp_MulReduce(Y->Z, A, B); /* z2 = (B)*((x+z)^2 + ((A-2)/4)(B)) */
|
||||
}
|
||||
|
||||
/* return P = P + Q, Q = 2Q */
|
||||
void ecp_Mont(XZ_POINT *P, XZ_POINT *Q, IN const U_WORD *Base)
|
||||
{
|
||||
U_WORD A[K_WORDS], B[K_WORDS], C[K_WORDS], D[K_WORDS], E[K_WORDS];
|
||||
/* x3 = ((x1-z1)(x2+z2) + (x1+z1)(x2-z2))^2*zb zb=1 */
|
||||
/* z3 = ((x1-z1)(x2+z2) - (x1+z1)(x2-z2))^2*xb xb=Base */
|
||||
ecp_SubReduce(A, P->X, P->Z); /* A = x1-z1 */
|
||||
ecp_AddReduce(B, P->X, P->Z); /* B = x1+z1 */
|
||||
ecp_SubReduce(C, Q->X, Q->Z); /* C = x2-z2 */
|
||||
ecp_AddReduce(D, Q->X, Q->Z); /* D = x2+z2 */
|
||||
ecp_MulReduce(A, A, D); /* A = (x1-z1)(x2+z2) */
|
||||
ecp_MulReduce(B, B, C); /* B = (x1+z1)(x2-z2) */
|
||||
ecp_AddReduce(E, A, B); /* E = (x1-z1)(x2+z2) + (x1+z1)(x2-z2) */
|
||||
ecp_SubReduce(B, A, B); /* B = (x1-z1)(x2+z2) - (x1+z1)(x2-z2) */
|
||||
ecp_SqrReduce(P->X, E); /* x3 = ((x1-z1)(x2+z2) + (x1+z1)(x2-z2))^2 */
|
||||
ecp_SqrReduce(A, B); /* A = ((x1-z1)(x2+z2) - (x1+z1)(x2-z2))^2 */
|
||||
ecp_MulReduce(P->Z, A, Base); /* z3 = ((x1-z1)(x2+z2) - (x1+z1)(x2-z2))^2*Base */
|
||||
|
||||
/* x4 = (x2+z2)^2 * (x2-z2)^2 */
|
||||
/* z4 = ((x2+z2)^2 - (x2-z2)^2)*((x2+z2)^2 + 121665((x2+z2)^2 - (x2-z2)^2)) */
|
||||
/* C = (x2-z2) */
|
||||
/* D = (x2+z2) */
|
||||
ecp_SqrReduce(A, D); /* A = (x2+z2)^2 */
|
||||
ecp_SqrReduce(B, C); /* B = (x2-z2)^2 */
|
||||
ecp_MulReduce(Q->X, A, B); /* x4 = (x2+z2)^2 * (x2-z2)^2 */
|
||||
ecp_SubReduce(B, A, B); /* B = (x2+z2)^2 - (x2-z2)^2 */
|
||||
ecp_WordMulAddReduce(A, A, 121665, B);
|
||||
ecp_MulReduce(Q->Z, A, B); /* z4 = B*((x2+z2)^2 + 121665*B) */
|
||||
}
|
||||
|
||||
/* Constant-time measure: */
|
||||
/* Use different set of parameters for bit=0 or bit=1 with no conditional jump */
|
||||
/* */
|
||||
#define ECP_MONT(n) j = (k >> n) & 1; ecp_Mont(PP[j], QP[j], X)
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Return point Q = k*P */
|
||||
/* K in a little-endian byte array */
|
||||
void ecp_PointMultiply(
|
||||
OUT U8 *PublicKey,
|
||||
IN const U8 *BasePoint,
|
||||
IN const U8 *SecretKey,
|
||||
IN int len)
|
||||
{
|
||||
int i, j, k;
|
||||
U_WORD X[K_WORDS];
|
||||
XZ_POINT P, Q, *PP[2], *QP[2];
|
||||
|
||||
ecp_BytesToWords(X, BasePoint);
|
||||
|
||||
/* 1: P = (2k+1)G, Q = (2k+2)G */
|
||||
/* 0: Q = (2k+1)G, P = (2k)G */
|
||||
|
||||
/* Find first non-zero bit */
|
||||
while (len-- > 0)
|
||||
{
|
||||
k = SecretKey[len];
|
||||
for (i = 0; i < 8; i++, k <<= 1)
|
||||
{
|
||||
/* P = kG, Q = (k+1)G */
|
||||
if (k & 0x80)
|
||||
{
|
||||
/* We have first non-zero bit
|
||||
// This is always bit 254 for keys created according to the spec.
|
||||
// Start with randomized base point
|
||||
*/
|
||||
|
||||
ecp_Add(P.Z, X, edp_custom_blinding.zr); /* P.Z = random */
|
||||
ecp_MulReduce(P.X, X, P.Z);
|
||||
ecp_MontDouble(&Q, &P);
|
||||
|
||||
PP[1] = &P; PP[0] = &Q;
|
||||
QP[1] = &Q; QP[0] = &P;
|
||||
|
||||
/* Everything we reference in the below loop are on the stack
|
||||
// and already touched (cached)
|
||||
*/
|
||||
|
||||
while (++i < 8) { k <<= 1; ECP_MONT(7); }
|
||||
while (len > 0)
|
||||
{
|
||||
k = SecretKey[--len];
|
||||
ECP_MONT(7);
|
||||
ECP_MONT(6);
|
||||
ECP_MONT(5);
|
||||
ECP_MONT(4);
|
||||
ECP_MONT(3);
|
||||
ECP_MONT(2);
|
||||
ECP_MONT(1);
|
||||
ECP_MONT(0);
|
||||
}
|
||||
|
||||
ecp_Inverse(Q.Z, P.Z);
|
||||
ecp_MulMod(X, P.X, Q.Z);
|
||||
ecp_WordsToBytes(PublicKey, X);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* K is 0 */
|
||||
mem_fill(PublicKey, 0, 32);
|
||||
}
|
||||
|
||||
/* -- DH key exchange interfaces ----------------------------------------- */
|
||||
|
||||
/* Return R = a*P where P is curve25519 base point */
|
||||
void x25519_BasePointMultiply(OUT U8 *r, IN const U8 *sk)
|
||||
{
|
||||
Ext_POINT S;
|
||||
U_WORD t[K_WORDS];
|
||||
|
||||
ecp_BytesToWords(t, sk);
|
||||
edp_BasePointMult(&S, t, edp_custom_blinding.zr);
|
||||
|
||||
/* Convert ed25519 point to x25519 point */
|
||||
|
||||
/* u = (1 + y)/(1 - y) = (Z + Y)/(Z - Y) */
|
||||
|
||||
ecp_AddReduce(S.t, S.z, S.y);
|
||||
ecp_SubReduce(S.z, S.z, S.y);
|
||||
ecp_Inverse(S.z, S.z);
|
||||
ecp_MulMod(S.t, S.t, S.z);
|
||||
ecp_WordsToBytes(r, S.t);
|
||||
}
|
||||
|
||||
/* Return public key associated with sk */
|
||||
void curve25519_dh_CalculatePublicKey_fast(
|
||||
unsigned char *pk, /* [32-bytes] OUT: Public key */
|
||||
unsigned char *sk) /* [32-bytes] IN/OUT: Your secret key */
|
||||
{
|
||||
ecp_TrimSecretKey(sk);
|
||||
/* Use faster method */
|
||||
x25519_BasePointMultiply(pk, sk);
|
||||
}
|
||||
|
||||
/* Return public key associated with sk */
|
||||
void curve25519_dh_CalculatePublicKey(
|
||||
unsigned char *pk, /* [32-bytes] OUT: Public key */
|
||||
unsigned char *sk) /* [32-bytes] IN/OUT: Your secret key */
|
||||
{
|
||||
ecp_TrimSecretKey(sk);
|
||||
ecp_PointMultiply(pk, ecp_BasePoint, sk, 32);
|
||||
}
|
||||
|
||||
/* Create a shared secret */
|
||||
void curve25519_dh_CreateSharedKey(
|
||||
unsigned char *shared, /* [32-bytes] OUT: Created shared key */
|
||||
const unsigned char *pk, /* [32-bytes] IN: Other side's public key */
|
||||
unsigned char *sk) /* [32-bytes] IN/OUT: Your secret key */
|
||||
{
|
||||
ecp_TrimSecretKey(sk);
|
||||
ecp_PointMultiply(shared, pk, sk, 32);
|
||||
}
|
410
source/extern/curve25519/source/curve25519_mehdi.c
vendored
Normal file
410
source/extern/curve25519/source/curve25519_mehdi.c
vendored
Normal file
@ -0,0 +1,410 @@
|
||||
/* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 mehdi sotoodeh
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#include "../include/external_calls.h"
|
||||
#include "curve25519_mehdi.h"
|
||||
|
||||
/*
|
||||
The curve used is y2 = x^3 + 486662x^2 + x, a Montgomery curve, over
|
||||
the prime field defined by the prime number 2^255 - 19, and it uses the
|
||||
base point x = 9.
|
||||
Protocol uses compressed elliptic point (only X coordinates), so it
|
||||
allows for efficient use of the Montgomery ladder for ECDH, using only
|
||||
XZ coordinates.
|
||||
|
||||
The curve is birationally equivalent to Ed25519 (Twisted Edwards curve).
|
||||
|
||||
b = 256
|
||||
p = 2**255 - 19
|
||||
l = 2**252 + 27742317777372353535851937790883648493
|
||||
|
||||
This library is a constant-time implementation of field operations
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
U32 X[8]; /* x = X/Z */
|
||||
U32 Z[8]; /* */
|
||||
} XZ_POINT;
|
||||
|
||||
const U32 _w_P[8] = {
|
||||
0xFFFFFFED,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
|
||||
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0x7FFFFFFF
|
||||
};
|
||||
|
||||
/* Maximum number of prime p that fits into 256-bits */
|
||||
const U32 _w_maxP[8] = { /* 2*P < 2**256 */
|
||||
0xFFFFFFDA,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
|
||||
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF
|
||||
};
|
||||
|
||||
void ecp_SetValue(U32* X, U32 value)
|
||||
{
|
||||
X[0] = value;
|
||||
X[1] = X[2] = X[3] = X[4] = X[5] = X[6] = X[7] = 0;
|
||||
}
|
||||
|
||||
/* Y = X */
|
||||
void ecp_Copy(U32* Y, const U32* X)
|
||||
{
|
||||
memcpy(Y, X, 8*sizeof(U32));
|
||||
}
|
||||
|
||||
int ecp_CmpNE(const U32* X, const U32* Y)
|
||||
{
|
||||
return ((X[0] ^ Y[0]) | (X[1] ^ Y[1]) | (X[2] ^ Y[2]) | (X[3] ^ Y[3]) |
|
||||
(X[4] ^ Y[4]) | (X[5] ^ Y[5]) | (X[6] ^ Y[6]) | (X[7] ^ Y[7]));
|
||||
}
|
||||
|
||||
int ecp_CmpLT(const U32* X, const U32* Y)
|
||||
{
|
||||
U32 T[8];
|
||||
return ecp_Sub(T, X, Y);
|
||||
}
|
||||
|
||||
#define ECP_ADD_C0(Y,X,V) c.u64 = (U64)(X) + (V); Y = c.u32.lo;
|
||||
#define ECP_ADD_C1(Y,X) c.u64 = (U64)(X) + c.u32.hi; Y = c.u32.lo;
|
||||
|
||||
#define ECP_SUB_C0(Y,X,V) c.s64 = (U64)(X) - (V); Y = c.u32.lo;
|
||||
#define ECP_SUB_C1(Y,X) c.s64 = (U64)(X) + (S64)c.s32.hi; Y = c.u32.lo;
|
||||
|
||||
#define ECP_MULSET_W0(Y,b,X) c.u64 = (U64)(b)*(X); Y = c.u32.lo;
|
||||
#define ECP_MULSET_W1(Y,b,X) c.u64 = (U64)(b)*(X) + c.u32.hi; Y = c.u32.lo;
|
||||
|
||||
#define ECP_MULADD_W0(Z,Y,b,X) c.u64 = (U64)(b)*(X) + (Y); Z = c.u32.lo;
|
||||
#define ECP_MULADD_W1(Z,Y,b,X) c.u64 = (U64)(b)*(X) + (U64)(Y) + c.u32.hi; Z = c.u32.lo;
|
||||
|
||||
#define ECP_ADD32(Z,X,Y) c.u64 = (U64)(X) + (Y); Z = c.u32.lo;
|
||||
#define ECP_ADC32(Z,X,Y) c.u64 = (U64)(X) + (U64)(Y) + c.u32.hi; Z = c.u32.lo;
|
||||
#define ECP_SUB32(Z,X,Y) b.s64 = (S64)(X) - (Y); Z = b.s32.lo;
|
||||
#define ECP_SBC32(Z,X,Y) b.s64 = (S64)(X) - (U64)(Y) + b.s32.hi; Z = b.s32.lo;
|
||||
|
||||
/* Computes Z = X+Y */
|
||||
U32 ecp_Add(U32* Z, const U32* X, const U32* Y)
|
||||
{
|
||||
M64 c;
|
||||
|
||||
ECP_ADD32(Z[0], X[0], Y[0]);
|
||||
ECP_ADC32(Z[1], X[1], Y[1]);
|
||||
ECP_ADC32(Z[2], X[2], Y[2]);
|
||||
ECP_ADC32(Z[3], X[3], Y[3]);
|
||||
ECP_ADC32(Z[4], X[4], Y[4]);
|
||||
ECP_ADC32(Z[5], X[5], Y[5]);
|
||||
ECP_ADC32(Z[6], X[6], Y[6]);
|
||||
ECP_ADC32(Z[7], X[7], Y[7]);
|
||||
return c.u32.hi;
|
||||
}
|
||||
|
||||
/* Computes Z = X-Y */
|
||||
S32 ecp_Sub(U32* Z, const U32* X, const U32* Y)
|
||||
{
|
||||
M64 b;
|
||||
ECP_SUB32(Z[0], X[0], Y[0]);
|
||||
ECP_SBC32(Z[1], X[1], Y[1]);
|
||||
ECP_SBC32(Z[2], X[2], Y[2]);
|
||||
ECP_SBC32(Z[3], X[3], Y[3]);
|
||||
ECP_SBC32(Z[4], X[4], Y[4]);
|
||||
ECP_SBC32(Z[5], X[5], Y[5]);
|
||||
ECP_SBC32(Z[6], X[6], Y[6]);
|
||||
ECP_SBC32(Z[7], X[7], Y[7]);
|
||||
return b.s32.hi;
|
||||
}
|
||||
|
||||
/* Computes Z = X+Y mod P */
|
||||
void ecp_AddReduce(U32* Z, const U32* X, const U32* Y)
|
||||
{
|
||||
M64 c;
|
||||
c.u32.hi = ecp_Add(Z, X, Y) * 38;
|
||||
|
||||
/* Z += c.u32.hi * 38 */
|
||||
ECP_ADD_C0(Z[0], Z[0], c.u32.hi);
|
||||
ECP_ADD_C1(Z[1], Z[1]);
|
||||
ECP_ADD_C1(Z[2], Z[2]);
|
||||
ECP_ADD_C1(Z[3], Z[3]);
|
||||
ECP_ADD_C1(Z[4], Z[4]);
|
||||
ECP_ADD_C1(Z[5], Z[5]);
|
||||
ECP_ADD_C1(Z[6], Z[6]);
|
||||
ECP_ADD_C1(Z[7], Z[7]);
|
||||
|
||||
/* One more carry at most */
|
||||
ECP_ADD_C0(Z[0], Z[0], c.u32.hi*38);
|
||||
ECP_ADD_C1(Z[1], Z[1]);
|
||||
ECP_ADD_C1(Z[2], Z[2]);
|
||||
ECP_ADD_C1(Z[3], Z[3]);
|
||||
ECP_ADD_C1(Z[4], Z[4]);
|
||||
ECP_ADD_C1(Z[5], Z[5]);
|
||||
ECP_ADD_C1(Z[6], Z[6]);
|
||||
ECP_ADD_C1(Z[7], Z[7]);
|
||||
}
|
||||
|
||||
/* Computes Z = X-Y mod P */
|
||||
void ecp_SubReduce(U32* Z, const U32* X, const U32* Y)
|
||||
{
|
||||
M64 c;
|
||||
c.u32.hi = ecp_Sub(Z, X, Y) & 38;
|
||||
|
||||
ECP_SUB_C0(Z[0], Z[0], c.u32.hi);
|
||||
ECP_SUB_C1(Z[1], Z[1]);
|
||||
ECP_SUB_C1(Z[2], Z[2]);
|
||||
ECP_SUB_C1(Z[3], Z[3]);
|
||||
ECP_SUB_C1(Z[4], Z[4]);
|
||||
ECP_SUB_C1(Z[5], Z[5]);
|
||||
ECP_SUB_C1(Z[6], Z[6]);
|
||||
ECP_SUB_C1(Z[7], Z[7]);
|
||||
|
||||
ECP_SUB_C0(Z[0], Z[0], c.u32.hi & 38);
|
||||
ECP_SUB_C1(Z[1], Z[1]);
|
||||
ECP_SUB_C1(Z[2], Z[2]);
|
||||
ECP_SUB_C1(Z[3], Z[3]);
|
||||
ECP_SUB_C1(Z[4], Z[4]);
|
||||
ECP_SUB_C1(Z[5], Z[5]);
|
||||
ECP_SUB_C1(Z[6], Z[6]);
|
||||
ECP_SUB_C1(Z[7], Z[7]);
|
||||
}
|
||||
|
||||
void ecp_Mod(U32 *X)
|
||||
{
|
||||
U32 T[8];
|
||||
U32 c = (U32)ecp_Sub(X, X, _w_P);
|
||||
|
||||
/* set T = 0 if c=0, else T = P */
|
||||
|
||||
T[0] = c & 0xFFFFFFED;
|
||||
T[1] = T[2] = T[3] = T[4] = T[5] = T[6] = c;
|
||||
T[7] = c >> 1;
|
||||
|
||||
ecp_Add(X, X, T); /* X += 0 or P */
|
||||
|
||||
/* In case there is another P there */
|
||||
|
||||
c = (U32)ecp_Sub(X, X, _w_P);
|
||||
|
||||
/* set T = 0 if c=0, else T = P */
|
||||
|
||||
T[0] = c & 0xFFFFFFED;
|
||||
T[1] = T[2] = T[3] = T[4] = T[5] = T[6] = c;
|
||||
T[7] = c >> 1;
|
||||
|
||||
ecp_Add(X, X, T); /* X += 0 or P */
|
||||
}
|
||||
|
||||
/* Computes Y = b*X */
|
||||
static void ecp_mul_set(U32* Y, U32 b, const U32* X)
|
||||
{
|
||||
M64 c;
|
||||
ECP_MULSET_W0(Y[0], b, X[0]);
|
||||
ECP_MULSET_W1(Y[1], b, X[1]);
|
||||
ECP_MULSET_W1(Y[2], b, X[2]);
|
||||
ECP_MULSET_W1(Y[3], b, X[3]);
|
||||
ECP_MULSET_W1(Y[4], b, X[4]);
|
||||
ECP_MULSET_W1(Y[5], b, X[5]);
|
||||
ECP_MULSET_W1(Y[6], b, X[6]);
|
||||
ECP_MULSET_W1(Y[7], b, X[7]);
|
||||
Y[8] = c.u32.hi;
|
||||
}
|
||||
|
||||
/* Computes Y += b*X */
|
||||
/* Addition is performed on lower 8-words of Y */
|
||||
static void ecp_mul_add(U32* Y, U32 b, const U32* X)
|
||||
{
|
||||
M64 c;
|
||||
ECP_MULADD_W0(Y[0], Y[0], b, X[0]);
|
||||
ECP_MULADD_W1(Y[1], Y[1], b, X[1]);
|
||||
ECP_MULADD_W1(Y[2], Y[2], b, X[2]);
|
||||
ECP_MULADD_W1(Y[3], Y[3], b, X[3]);
|
||||
ECP_MULADD_W1(Y[4], Y[4], b, X[4]);
|
||||
ECP_MULADD_W1(Y[5], Y[5], b, X[5]);
|
||||
ECP_MULADD_W1(Y[6], Y[6], b, X[6]);
|
||||
ECP_MULADD_W1(Y[7], Y[7], b, X[7]);
|
||||
Y[8] = c.u32.hi;
|
||||
}
|
||||
|
||||
/* Computes Z = Y + b*X and return carry */
|
||||
void ecp_WordMulAddReduce(U32 *Z, const U32* Y, U32 b, const U32* X)
|
||||
{
|
||||
M64 c;
|
||||
ECP_MULADD_W0(Z[0], Y[0], b, X[0]);
|
||||
ECP_MULADD_W1(Z[1], Y[1], b, X[1]);
|
||||
ECP_MULADD_W1(Z[2], Y[2], b, X[2]);
|
||||
ECP_MULADD_W1(Z[3], Y[3], b, X[3]);
|
||||
ECP_MULADD_W1(Z[4], Y[4], b, X[4]);
|
||||
ECP_MULADD_W1(Z[5], Y[5], b, X[5]);
|
||||
ECP_MULADD_W1(Z[6], Y[6], b, X[6]);
|
||||
ECP_MULADD_W1(Z[7], Y[7], b, X[7]);
|
||||
|
||||
/* Z += c.u32.hi * 38 */
|
||||
ECP_MULADD_W0(Z[0], Z[0], c.u32.hi, 38);
|
||||
ECP_ADD_C1(Z[1], Z[1]);
|
||||
ECP_ADD_C1(Z[2], Z[2]);
|
||||
ECP_ADD_C1(Z[3], Z[3]);
|
||||
ECP_ADD_C1(Z[4], Z[4]);
|
||||
ECP_ADD_C1(Z[5], Z[5]);
|
||||
ECP_ADD_C1(Z[6], Z[6]);
|
||||
ECP_ADD_C1(Z[7], Z[7]);
|
||||
|
||||
/* One more time at most */
|
||||
ECP_MULADD_W0(Z[0], Z[0], c.u32.hi, 38);
|
||||
ECP_ADD_C1(Z[1], Z[1]);
|
||||
ECP_ADD_C1(Z[2], Z[2]);
|
||||
ECP_ADD_C1(Z[3], Z[3]);
|
||||
ECP_ADD_C1(Z[4], Z[4]);
|
||||
ECP_ADD_C1(Z[5], Z[5]);
|
||||
ECP_ADD_C1(Z[6], Z[6]);
|
||||
ECP_ADD_C1(Z[7], Z[7]);
|
||||
}
|
||||
|
||||
/* Computes Z = X*Y mod P. */
|
||||
/* Output fits into 8 words but could be greater than P */
|
||||
void ecp_MulReduce(U32* Z, const U32* X, const U32* Y)
|
||||
{
|
||||
U32 T[16];
|
||||
|
||||
ecp_mul_set(T+0, X[0], Y);
|
||||
ecp_mul_add(T+1, X[1], Y);
|
||||
ecp_mul_add(T+2, X[2], Y);
|
||||
ecp_mul_add(T+3, X[3], Y);
|
||||
ecp_mul_add(T+4, X[4], Y);
|
||||
ecp_mul_add(T+5, X[5], Y);
|
||||
ecp_mul_add(T+6, X[6], Y);
|
||||
ecp_mul_add(T+7, X[7], Y);
|
||||
|
||||
/* We have T = X*Y, now do the reduction in size */
|
||||
|
||||
ecp_WordMulAddReduce(Z, T, 38, T+8);
|
||||
}
|
||||
|
||||
/* Computes Z = X*Y */
|
||||
void ecp_Mul(U32* Z, const U32* X, const U32* Y)
|
||||
{
|
||||
ecp_mul_set(Z+0, X[0], Y);
|
||||
ecp_mul_add(Z+1, X[1], Y);
|
||||
ecp_mul_add(Z+2, X[2], Y);
|
||||
ecp_mul_add(Z+3, X[3], Y);
|
||||
ecp_mul_add(Z+4, X[4], Y);
|
||||
ecp_mul_add(Z+5, X[5], Y);
|
||||
ecp_mul_add(Z+6, X[6], Y);
|
||||
ecp_mul_add(Z+7, X[7], Y);
|
||||
}
|
||||
|
||||
/* Computes Z = X*Y mod P. */
|
||||
void ecp_SqrReduce(U32* Y, const U32* X)
|
||||
{
|
||||
/* TBD: Implementation is based on multiply */
|
||||
/* Optimize for squaring */
|
||||
|
||||
U32 T[16];
|
||||
|
||||
ecp_mul_set(T+0, X[0], X);
|
||||
ecp_mul_add(T+1, X[1], X);
|
||||
ecp_mul_add(T+2, X[2], X);
|
||||
ecp_mul_add(T+3, X[3], X);
|
||||
ecp_mul_add(T+4, X[4], X);
|
||||
ecp_mul_add(T+5, X[5], X);
|
||||
ecp_mul_add(T+6, X[6], X);
|
||||
ecp_mul_add(T+7, X[7], X);
|
||||
|
||||
/* We have T = X*X, now do the reduction in size */
|
||||
|
||||
ecp_WordMulAddReduce(Y, T, 38, T+8);
|
||||
}
|
||||
|
||||
/* Computes Z = X*Y mod P. */
|
||||
void ecp_MulMod(U32* Z, const U32* X, const U32* Y)
|
||||
{
|
||||
ecp_MulReduce(Z, X, Y);
|
||||
ecp_Mod(Z);
|
||||
}
|
||||
|
||||
/* Courtesy of DJB */
|
||||
/* Return out = 1/z mod P */
|
||||
void ecp_Inverse(U32 *out, const U32 *z)
|
||||
{
|
||||
int i;
|
||||
U32 t0[8],t1[8],z2[8],z9[8],z11[8];
|
||||
U32 z2_5_0[8],z2_10_0[8],z2_20_0[8],z2_50_0[8],z2_100_0[8];
|
||||
|
||||
/* 2 */ ecp_SqrReduce(z2,z);
|
||||
/* 4 */ ecp_SqrReduce(t1,z2);
|
||||
/* 8 */ ecp_SqrReduce(t0,t1);
|
||||
/* 9 */ ecp_MulReduce(z9,t0,z);
|
||||
/* 11 */ ecp_MulReduce(z11,z9,z2);
|
||||
/* 22 */ ecp_SqrReduce(t0,z11);
|
||||
/* 2^5 - 2^0 = 31 */ ecp_MulReduce(z2_5_0,t0,z9);
|
||||
|
||||
/* 2^6 - 2^1 */ ecp_SqrReduce(t0,z2_5_0);
|
||||
/* 2^7 - 2^2 */ ecp_SqrReduce(t1,t0);
|
||||
/* 2^8 - 2^3 */ ecp_SqrReduce(t0,t1);
|
||||
/* 2^9 - 2^4 */ ecp_SqrReduce(t1,t0);
|
||||
/* 2^10 - 2^5 */ ecp_SqrReduce(t0,t1);
|
||||
/* 2^10 - 2^0 */ ecp_MulReduce(z2_10_0,t0,z2_5_0);
|
||||
|
||||
/* 2^11 - 2^1 */ ecp_SqrReduce(t0,z2_10_0);
|
||||
/* 2^12 - 2^2 */ ecp_SqrReduce(t1,t0);
|
||||
/* 2^20 - 2^10 */ for (i = 2;i < 10;i += 2) {
|
||||
ecp_SqrReduce(t0,t1);
|
||||
ecp_SqrReduce(t1,t0); }
|
||||
/* 2^20 - 2^0 */ ecp_MulReduce(z2_20_0,t1,z2_10_0);
|
||||
|
||||
/* 2^21 - 2^1 */ ecp_SqrReduce(t0,z2_20_0);
|
||||
/* 2^22 - 2^2 */ ecp_SqrReduce(t1,t0);
|
||||
/* 2^40 - 2^20 */ for (i = 2;i < 20;i += 2) {
|
||||
ecp_SqrReduce(t0,t1);
|
||||
ecp_SqrReduce(t1,t0); }
|
||||
/* 2^40 - 2^0 */ ecp_MulReduce(t0,t1,z2_20_0);
|
||||
|
||||
/* 2^41 - 2^1 */ ecp_SqrReduce(t1,t0);
|
||||
/* 2^42 - 2^2 */ ecp_SqrReduce(t0,t1);
|
||||
/* 2^50 - 2^10 */ for (i = 2;i < 10;i += 2) {
|
||||
ecp_SqrReduce(t1,t0);
|
||||
ecp_SqrReduce(t0,t1); }
|
||||
/* 2^50 - 2^0 */ ecp_MulReduce(z2_50_0,t0,z2_10_0);
|
||||
|
||||
/* 2^51 - 2^1 */ ecp_SqrReduce(t0,z2_50_0);
|
||||
/* 2^52 - 2^2 */ ecp_SqrReduce(t1,t0);
|
||||
/* 2^100 - 2^50 */ for (i = 2;i < 50;i += 2) {
|
||||
ecp_SqrReduce(t0,t1);
|
||||
ecp_SqrReduce(t1,t0); }
|
||||
/* 2^100 - 2^0 */ ecp_MulReduce(z2_100_0,t1,z2_50_0);
|
||||
|
||||
/* 2^101 - 2^1 */ ecp_SqrReduce(t1,z2_100_0);
|
||||
/* 2^102 - 2^2 */ ecp_SqrReduce(t0,t1);
|
||||
/* 2^200 - 2^100 */ for (i = 2;i < 100;i += 2) {
|
||||
ecp_SqrReduce(t1,t0);
|
||||
ecp_SqrReduce(t0,t1); }
|
||||
/* 2^200 - 2^0 */ ecp_MulReduce(t1,t0,z2_100_0);
|
||||
|
||||
/* 2^201 - 2^1 */ ecp_SqrReduce(t0,t1);
|
||||
/* 2^202 - 2^2 */ ecp_SqrReduce(t1,t0);
|
||||
/* 2^250 - 2^50 */ for (i = 2;i < 50;i += 2) {
|
||||
ecp_SqrReduce(t0,t1);
|
||||
ecp_SqrReduce(t1,t0); }
|
||||
/* 2^250 - 2^0 */ ecp_MulReduce(t0,t1,z2_50_0);
|
||||
|
||||
/* 2^251 - 2^1 */ ecp_SqrReduce(t1,t0);
|
||||
/* 2^252 - 2^2 */ ecp_SqrReduce(t0,t1);
|
||||
/* 2^253 - 2^3 */ ecp_SqrReduce(t1,t0);
|
||||
/* 2^254 - 2^4 */ ecp_SqrReduce(t0,t1);
|
||||
/* 2^255 - 2^5 */ ecp_SqrReduce(t1,t0);
|
||||
/* 2^255 - 21 */ ecp_MulReduce(out,t1,z11);
|
||||
}
|
||||
|
175
source/extern/curve25519/source/curve25519_mehdi.h
vendored
Normal file
175
source/extern/curve25519/source/curve25519_mehdi.h
vendored
Normal file
@ -0,0 +1,175 @@
|
||||
/* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 mehdi sotoodeh
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __curve25519_mehdi_h__
|
||||
#define __curve25519_mehdi_h__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "BaseTypes.h"
|
||||
|
||||
#define ECP_VERSION_STR "1.2.0"
|
||||
|
||||
#ifdef USE_ASM_LIB
|
||||
#define U_WORD U64
|
||||
#define S_WORD S64
|
||||
#define WORDSIZE_64
|
||||
#define W64(lo,hi) ((U64)hi<<32)+lo
|
||||
#else
|
||||
#define U_WORD U32
|
||||
#define S_WORD S32
|
||||
#define WORDSIZE_32
|
||||
#define W64(lo,hi) lo,hi
|
||||
#endif
|
||||
|
||||
#define K_BYTES 32
|
||||
#define K_WORDS (K_BYTES/sizeof(U_WORD))
|
||||
|
||||
#define W256(x0,x1,x2,x3,x4,x5,x6,x7) {W64(x0,x1),W64(x2,x3),W64(x4,x5),W64(x6,x7)}
|
||||
|
||||
/* Affine coordinates */
|
||||
typedef struct {
|
||||
U_WORD x[K_WORDS];
|
||||
U_WORD y[K_WORDS];
|
||||
} Affine_POINT;
|
||||
|
||||
/* Projective coordinates */
|
||||
typedef struct {
|
||||
U_WORD x[K_WORDS]; /* x/z */
|
||||
U_WORD y[K_WORDS]; /* y/z */
|
||||
U_WORD z[K_WORDS];
|
||||
U_WORD t[K_WORDS]; /* xy/z */
|
||||
} Ext_POINT;
|
||||
|
||||
/* pre-computed, extended point */
|
||||
typedef struct
|
||||
{
|
||||
U_WORD YpX[K_WORDS]; /* Y+X */
|
||||
U_WORD YmX[K_WORDS]; /* Y-X */
|
||||
U_WORD T2d[K_WORDS]; /* 2d*T */
|
||||
U_WORD Z2[K_WORDS]; /* 2*Z */
|
||||
} PE_POINT;
|
||||
|
||||
/* pre-computed, Affine point */
|
||||
typedef struct
|
||||
{
|
||||
U_WORD YpX[K_WORDS]; /* Y+X */
|
||||
U_WORD YmX[K_WORDS]; /* Y-X */
|
||||
U_WORD T2d[K_WORDS]; /* 2d*T */
|
||||
} PA_POINT;
|
||||
|
||||
typedef struct {
|
||||
U_WORD bl[K_WORDS];
|
||||
U_WORD zr[K_WORDS];
|
||||
PE_POINT BP;
|
||||
} EDP_BLINDING_CTX;
|
||||
|
||||
extern const U8 ecp_BasePoint[K_BYTES];
|
||||
|
||||
/* Return point Q = k*P */
|
||||
void ecp_PointMultiply(OUT U8 *Q, IN const U8 *P, IN const U8 *K, IN int len);
|
||||
|
||||
/* Set low and high bits */
|
||||
void ecp_TrimSecretKey(U8 *X);
|
||||
|
||||
/* -- utils ----------------------------------------------------------------- */
|
||||
|
||||
/* Convert big-endian byte array to little-endian byte array and vice versa */
|
||||
U8* ecp_ReverseByteOrder(OUT U8 *Y, IN const U8 *X);
|
||||
/* Convert little-endian byte array to little-endian word array */
|
||||
U_WORD* ecp_BytesToWords(OUT U_WORD *Y, IN const U8 *X);
|
||||
/* Convert little-endian word array to little-endian byte array */
|
||||
U8* ecp_WordsToBytes(OUT U8 *Y, IN const U_WORD *X);
|
||||
U8* ecp_EncodeInt(OUT U8 *Y, IN const U_WORD *X, IN U8 parity);
|
||||
U8 ecp_DecodeInt(OUT U_WORD *Y, IN const U8 *X);
|
||||
|
||||
/* -- base point order ------------------------------------------------------ */
|
||||
|
||||
/* Z = (X*Y)/R mod BPO */
|
||||
void eco_MontMul(OUT U_WORD *Z, IN const U_WORD *X, IN const U_WORD *Y);
|
||||
/* Return Y = X*R mod BPO */
|
||||
void eco_ToMont(OUT U_WORD *Y, IN const U_WORD *X);
|
||||
/* Return Y = X/R mod BPO */
|
||||
void eco_FromMont(OUT U_WORD *Y, IN const U_WORD *X);
|
||||
/* Calculate Y = X**E mod BPO */
|
||||
void eco_ExpModBPO(OUT U_WORD *Y, IN const U_WORD *X, IN const U8 *E, IN int bytes);
|
||||
/* Calculate Y = 1/X mod BPO */
|
||||
void eco_InvModBPO(OUT U_WORD *Y, IN const U_WORD *X);
|
||||
/* Z = X*Y mod BPO */
|
||||
void eco_MulReduce(OUT U_WORD *Z, IN const U_WORD *X, IN const U_WORD *Y);
|
||||
/* Return Y = D mod BPO where D is 512-bit big-endian byte array (i.e SHA512 digest) */
|
||||
void eco_DigestToWords( OUT U_WORD *Y, IN const U8 *D);
|
||||
/* Z = X + Y mod BPO */
|
||||
void eco_AddReduce(OUT U_WORD *Z, IN const U_WORD *X, IN const U_WORD *Y);
|
||||
/* X mod BPO */
|
||||
void eco_Mod(U_WORD *X);
|
||||
|
||||
#define ed25519_PackPoint(buff, Y, parity) ecp_EncodeInt(buff, Y, (U8)(parity & 1))
|
||||
|
||||
/* -- big-number ------------------------------------------------------------ */
|
||||
U_WORD ecp_Add(U_WORD* Z, const U_WORD* X, const U_WORD* Y);
|
||||
S_WORD ecp_Sub(U_WORD* Z, const U_WORD* X, const U_WORD* Y);
|
||||
void ecp_SetValue(U_WORD* X, U_WORD value);
|
||||
void ecp_Copy(U_WORD* Y, const U_WORD* X);
|
||||
void ecp_AddReduce(U_WORD* Z, const U_WORD* X, const U_WORD* Y);
|
||||
void ecp_SubReduce(U_WORD* Z, const U_WORD* X, const U_WORD* Y);
|
||||
void ecp_MulReduce(U_WORD* Z, const U_WORD* X, const U_WORD* Y);
|
||||
void ecp_SqrReduce(U_WORD* Y, const U_WORD* X);
|
||||
void ecp_ModExp2523(U_WORD *Y, const U_WORD *X);
|
||||
void ecp_Inverse(U_WORD *out, const U_WORD *z);
|
||||
void ecp_MulMod(U_WORD* Z, const U_WORD* X, const U_WORD* Y);
|
||||
void ecp_Mul(U_WORD* Z, const U_WORD* X, const U_WORD* Y);
|
||||
/* Computes Y = b*X */
|
||||
void ecp_WordMulSet(U_WORD *Y, U_WORD b, const U_WORD* X);
|
||||
/* Computes Z = Y + b*X and return carry */
|
||||
U_WORD ecp_WordMulAdd(U_WORD *Z, const U_WORD* Y, U_WORD b, const U_WORD* X);
|
||||
/* Computes Z = Y + b*X */
|
||||
void ecp_WordMulAddReduce(U_WORD *Z, const U_WORD* Y, U_WORD b, const U_WORD* X);
|
||||
void ecp_Mod(U_WORD* X);
|
||||
int ecp_CmpNE(const U_WORD* X, const U_WORD* Y);
|
||||
int ecp_CmpLT(const U_WORD* X, const U_WORD* Y);
|
||||
/* Calculate: Y = [b:X] mod BPO */
|
||||
void eco_ReduceHiWord(U_WORD* Y, U_WORD b, const U_WORD* X);
|
||||
|
||||
/* -- ed25519 --------------------------------------------------------------- */
|
||||
void ed25519_UnpackPoint(Affine_POINT *r, const unsigned char *p);
|
||||
void ed25519_CalculateX(OUT U_WORD *X, IN const U_WORD *Y, U_WORD parity);
|
||||
void edp_AddAffinePoint(Ext_POINT *p, const PA_POINT *q);
|
||||
void edp_AddBasePoint(Ext_POINT *p);
|
||||
void edp_AddPoint(Ext_POINT *r, const Ext_POINT *p, const PE_POINT *q);
|
||||
void edp_DoublePoint(Ext_POINT *p);
|
||||
void edp_ComputePermTable(PE_POINT *qtable, Ext_POINT *Q);
|
||||
void edp_ExtPoint2PE(PE_POINT *r, const Ext_POINT *p);
|
||||
void edp_BasePointMult(OUT Ext_POINT *S, IN const U_WORD *sk, IN const U_WORD *R);
|
||||
void edp_BasePointMultiply(OUT Affine_POINT *Q, IN const U_WORD *sk,
|
||||
IN const void *blinding);
|
||||
void ecp_4Folds(U8* Y, const U_WORD* X);
|
||||
void ecp_8Folds(U8* Y, const U_WORD* X);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __curve25519_mehdi_h__ */
|
155
source/extern/curve25519/source/curve25519_order.c
vendored
Normal file
155
source/extern/curve25519/source/curve25519_order.c
vendored
Normal file
@ -0,0 +1,155 @@
|
||||
/* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 mehdi sotoodeh
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "curve25519_mehdi.h"
|
||||
|
||||
/*
|
||||
This library provides support for mod BPO (Base Point Order) operations
|
||||
|
||||
BPO = 2**252 + 27742317777372353535851937790883648493
|
||||
BPO = 0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED
|
||||
|
||||
If you keep adding points together, the result repeats every BPO times.
|
||||
Based on this, you may use:
|
||||
|
||||
public_key = (private_key mod BPO)*BasePoint
|
||||
Split key example:
|
||||
k1 = random()
|
||||
k2 = 1/k1 mod BPO --> k1*k2 = 1 mod BPO
|
||||
P1 = k1*P0 --> P2 = k2*P1 = k2*k1*P0 = P0
|
||||
See selftest code for some examples of BPO usage
|
||||
|
||||
This library is used for implementation of EdDSA sign/verify.
|
||||
*/
|
||||
|
||||
const U_WORD _w_NxBPO[16][K_WORDS] = { /* n*BPO */
|
||||
W256(0,0,0,0,0,0,0,0),
|
||||
W256(0x5CF5D3ED,0x5812631A,0xA2F79CD6,0x14DEF9DE,0,0,0,0x10000000),
|
||||
W256(0xB9EBA7DA,0xB024C634,0x45EF39AC,0x29BDF3BD,0,0,0,0x20000000),
|
||||
W256(0x16E17BC7,0x0837294F,0xE8E6D683,0x3E9CED9B,0,0,0,0x30000000),
|
||||
W256(0x73D74FB4,0x60498C69,0x8BDE7359,0x537BE77A,0,0,0,0x40000000),
|
||||
W256(0xD0CD23A1,0xB85BEF83,0x2ED6102F,0x685AE159,0,0,0,0x50000000),
|
||||
W256(0x2DC2F78E,0x106E529E,0xD1CDAD06,0x7D39DB37,0,0,0,0x60000000),
|
||||
W256(0x8AB8CB7B,0x6880B5B8,0x74C549DC,0x9218D516,0,0,0,0x70000000),
|
||||
W256(0xE7AE9F68,0xC09318D2,0x17BCE6B2,0xA6F7CEF5,0,0,0,0x80000000),
|
||||
W256(0x44A47355,0x18A57BED,0xBAB48389,0xBBD6C8D3,0,0,0,0x90000000),
|
||||
W256(0xA19A4742,0x70B7DF07,0x5DAC205F,0xD0B5C2B2,0,0,0,0xA0000000),
|
||||
W256(0xFE901B2F,0xC8CA4221,0x00A3BD35,0xE594BC91,0,0,0,0xB0000000),
|
||||
W256(0x5B85EF1C,0x20DCA53C,0xA39B5A0C,0xFA73B66F,0,0,0,0xC0000000),
|
||||
W256(0xB87BC309,0x78EF0856,0x4692F6E2,0x0F52B04E,1,0,0,0xD0000000),
|
||||
W256(0x157196F6,0xD1016B71,0xE98A93B8,0x2431AA2C,1,0,0,0xE0000000),
|
||||
W256(0x72676AE3,0x2913CE8B,0x8C82308F,0x3910A40B,1,0,0,0xF0000000)
|
||||
};
|
||||
|
||||
#define minusR_0 0xCF5D3ED0
|
||||
#define minusR_1 0x812631A5
|
||||
#define minusR_2 0x2F79CD65
|
||||
#define minusR_3 0x4DEF9DEA
|
||||
#define minusR_4 1
|
||||
#define minusR_5 0
|
||||
#define minusR_6 0
|
||||
#define minusR_7 0
|
||||
|
||||
/* Calculate: Y = [b:X] mod BPO
|
||||
// For R = 2^256, we calculate Y = b*R + X mod BPO
|
||||
// Since -R mod BPO is only 129-bits, it reduces number of multiplications if
|
||||
// we calculate: Y = X - b*(-R) mod BPO instead
|
||||
// Note that b*(-R) is 161-bits at most and does not need reduction.
|
||||
*/
|
||||
void eco_ReduceHiWord(U32* Y, U32 b, const U32* X)
|
||||
{
|
||||
M64 c;
|
||||
U32 T[8];
|
||||
|
||||
/* Set T = b*(-R) */
|
||||
|
||||
c.u64 = (U64)b*minusR_0;
|
||||
T[0] = c.u32.lo;
|
||||
c.u64 = (U64)b*minusR_1 + c.u32.hi;
|
||||
T[1] = c.u32.lo;
|
||||
c.u64 = (U64)b*minusR_2 + c.u32.hi;
|
||||
T[2] = c.u32.lo;
|
||||
c.u64 = (U64)b*minusR_3 + c.u32.hi;
|
||||
T[3] = c.u32.lo;
|
||||
c.u64 = (U64)b + c.u32.hi;
|
||||
T[4] = c.u32.lo;
|
||||
T[5] = c.u32.hi;
|
||||
T[6] = 0;
|
||||
T[7] = 0;
|
||||
|
||||
/* Y = X - T */
|
||||
c.s32.hi = ecp_Sub(Y, X, T);
|
||||
|
||||
/* Add BPO if there is a borrow */
|
||||
|
||||
ecp_Add(Y, Y, _w_NxBPO[c.s32.hi & 1]);
|
||||
}
|
||||
|
||||
/* Z = X*Y mod BPO */
|
||||
void eco_MulReduce(OUT U32 *Z, IN const U32 *X, IN const U32 *Y)
|
||||
{
|
||||
U32 T[16];
|
||||
ecp_Mul(T, X, Y); /* T = X*Y */
|
||||
eco_ReduceHiWord(T+7, T[15], T+7);
|
||||
eco_ReduceHiWord(T+6, T[14], T+6);
|
||||
eco_ReduceHiWord(T+5, T[13], T+5);
|
||||
eco_ReduceHiWord(T+4, T[12], T+4);
|
||||
eco_ReduceHiWord(T+3, T[11], T+3);
|
||||
eco_ReduceHiWord(T+2, T[10], T+2);
|
||||
eco_ReduceHiWord(T+1, T[9], T+1);
|
||||
eco_ReduceHiWord(Z, T[8], T+0);
|
||||
}
|
||||
|
||||
/* X mod BPO */
|
||||
void eco_Mod(U32 *X)
|
||||
{
|
||||
S32 c = ecp_Sub(X, X, _w_NxBPO[X[7] >> 28]);
|
||||
ecp_Add(X, X, _w_NxBPO[c & 1]);
|
||||
}
|
||||
|
||||
/* Z = X + Y mod BPO */
|
||||
void eco_AddReduce(OUT U32 *Z, IN const U32 *X, IN const U32 *Y)
|
||||
{
|
||||
U32 c = ecp_Add(Z, X, Y);
|
||||
eco_ReduceHiWord(Z, c, Z);
|
||||
}
|
||||
|
||||
/* Return Y = D mod BPO where D is 512-bit message digest (i.e SHA512 digest) */
|
||||
void eco_DigestToWords( OUT U32 *Y, IN const U8 *md)
|
||||
{
|
||||
U32 T[16];
|
||||
|
||||
/* We use digest value as little-endian byte array. */
|
||||
ecp_BytesToWords(T, md);
|
||||
ecp_BytesToWords(T+8, md+32);
|
||||
|
||||
eco_ReduceHiWord(T+7, T[15], T+7);
|
||||
eco_ReduceHiWord(T+6, T[14], T+6);
|
||||
eco_ReduceHiWord(T+5, T[13], T+5);
|
||||
eco_ReduceHiWord(T+4, T[12], T+4);
|
||||
eco_ReduceHiWord(T+3, T[11], T+3);
|
||||
eco_ReduceHiWord(T+2, T[10], T+2);
|
||||
eco_ReduceHiWord(T+1, T[9], T+1);
|
||||
eco_ReduceHiWord(Y, T[8], T+0);
|
||||
}
|
153
source/extern/curve25519/source/curve25519_utils.c
vendored
Normal file
153
source/extern/curve25519/source/curve25519_utils.c
vendored
Normal file
@ -0,0 +1,153 @@
|
||||
/* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 mehdi sotoodeh
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "curve25519_mehdi.h"
|
||||
|
||||
/* Trim private key */
|
||||
void ecp_TrimSecretKey(U8 *X)
|
||||
{
|
||||
X[0] &= 0xf8;
|
||||
X[31] = (X[31] | 0x40) & 0x7f;
|
||||
}
|
||||
|
||||
/* Convert big-endian byte array to little-endian byte array and vice versa */
|
||||
U8* ecp_ReverseByteOrder(OUT U8 *Y, IN const U8 *X)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 32; i++) Y[i] = X[31-i];
|
||||
return Y;
|
||||
}
|
||||
|
||||
/* Convert little-endian byte array to little-endian word array */
|
||||
U32* ecp_BytesToWords(OUT U32 *Y, IN const U8 *X)
|
||||
{
|
||||
int i;
|
||||
M32 m;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
m.u8.b0 = *X++;
|
||||
m.u8.b1 = *X++;
|
||||
m.u8.b2 = *X++;
|
||||
m.u8.b3 = *X++;
|
||||
|
||||
Y[i] = m.u32;
|
||||
}
|
||||
return Y;
|
||||
}
|
||||
|
||||
/* Convert little-endian word array to little-endian byte array */
|
||||
U8* ecp_WordsToBytes(OUT U8 *Y, IN const U32 *X)
|
||||
{
|
||||
int i;
|
||||
M32 m;
|
||||
|
||||
for (i = 0; i < 32;)
|
||||
{
|
||||
m.u32 = *X++;
|
||||
Y[i++] = m.u8.b0;
|
||||
Y[i++] = m.u8.b1;
|
||||
Y[i++] = m.u8.b2;
|
||||
Y[i++] = m.u8.b3;
|
||||
}
|
||||
return Y;
|
||||
}
|
||||
|
||||
U8* ecp_EncodeInt(OUT U8 *Y, IN const U32 *X, IN U8 parity)
|
||||
{
|
||||
int i;
|
||||
M32 m;
|
||||
|
||||
for (i = 0; i < 28;)
|
||||
{
|
||||
m.u32 = *X++;
|
||||
Y[i++] = m.u8.b0;
|
||||
Y[i++] = m.u8.b1;
|
||||
Y[i++] = m.u8.b2;
|
||||
Y[i++] = m.u8.b3;
|
||||
}
|
||||
|
||||
m.u32 = *X;
|
||||
Y[28] = m.u8.b0;
|
||||
Y[29] = m.u8.b1;
|
||||
Y[30] = m.u8.b2;
|
||||
Y[31] = (U8)((m.u8.b3 & 0x7f) | (parity << 7));
|
||||
|
||||
return Y;
|
||||
}
|
||||
|
||||
U8 ecp_DecodeInt(OUT U32 *Y, IN const U8 *X)
|
||||
{
|
||||
int i;
|
||||
M32 m;
|
||||
|
||||
for (i = 0; i < 7; i++)
|
||||
{
|
||||
m.u8.b0 = *X++;
|
||||
m.u8.b1 = *X++;
|
||||
m.u8.b2 = *X++;
|
||||
m.u8.b3 = *X++;
|
||||
|
||||
Y[i] = m.u32;
|
||||
}
|
||||
|
||||
m.u8.b0 = *X++;
|
||||
m.u8.b1 = *X++;
|
||||
m.u8.b2 = *X++;
|
||||
m.u8.b3 = *X & 0x7f;
|
||||
|
||||
Y[7] = m.u32;
|
||||
|
||||
return (U8)((*X >> 7) & 1);
|
||||
}
|
||||
|
||||
void ecp_4Folds(U8* Y, const U32* X)
|
||||
{
|
||||
int i, j;
|
||||
U8 a, b;
|
||||
for (i = 32; i-- > 0; Y++)
|
||||
{
|
||||
a = 0;
|
||||
b = 0;
|
||||
for (j = 8; j > 1;)
|
||||
{
|
||||
j -= 2;
|
||||
a = (a << 1) + ((X[j+1] >> i) & 1);
|
||||
b = (b << 1) + ((X[j] >> i) & 1);
|
||||
}
|
||||
Y[0] = a;
|
||||
Y[32] = b;
|
||||
}
|
||||
}
|
||||
|
||||
void ecp_8Folds(U8* Y, const U32* X)
|
||||
{
|
||||
int i, j;
|
||||
U8 a = 0;
|
||||
for (i = 32; i-- > 0;)
|
||||
{
|
||||
for (j = 8; j-- > 0;) a = (a << 1) + ((X[j] >> i) & 1);
|
||||
*Y++ = a;
|
||||
}
|
||||
}
|
27
source/extern/curve25519/source/custom_blind.c
vendored
Normal file
27
source/extern/curve25519/source/custom_blind.c
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
/* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 mehdi sotoodeh
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "curve25519_mehdi.h"
|
||||
#include "custom_blind.h"
|
||||
|
11
source/extern/curve25519/source/custom_blind.h
vendored
Normal file
11
source/extern/curve25519/source/custom_blind.h
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
EDP_BLINDING_CTX edp_custom_blinding =
|
||||
{
|
||||
W256(0xDB763B3D,0x2F33DD36,0xF8DC6F74,0x98C50273,0x8216E0D5,0x1AA522E6,0x6BFD2924,0x04BEFBE2),
|
||||
W256(0x73FF0C54,0x459E8BA8,0x84F9550B,0xDBF5F46A,0x6DB0E537,0x65F44FFD,0x2AED4E78,0x2CF92B82),
|
||||
{
|
||||
W256(0xAA6B12E6,0x7E6A2126,0x2E016899,0x80453AE0,0x6F300787,0x7A7E739E,0x264D5BA3,0x4C34AA79),
|
||||
W256(0x52EA83C8,0xE4156040,0x0792FA4C,0x97CA4A43,0x3C9611E1,0x2198FE81,0x41AEAAE6,0x11919AD1),
|
||||
W256(0x54A55516,0xCD8ADA8A,0x820A3D65,0xF85C2DB2,0x06667F3B,0xFF1E45F7,0x26BD6148,0x7F4E9D95),
|
||||
W256(0xA4986374,0x2C1BF6DE,0x57ABC779,0x7C913D04,0xFA1127FA,0x1D7E8692,0xDE0E0680,0xC636320A)
|
||||
}
|
||||
};
|
419
source/extern/curve25519/source/ed25519_sign.c
vendored
Normal file
419
source/extern/curve25519/source/ed25519_sign.c
vendored
Normal file
@ -0,0 +1,419 @@
|
||||
/* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 mehdi sotoodeh
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "../include/external_calls.h"
|
||||
#include "curve25519_mehdi.h"
|
||||
#include "../include/ed25519_signature.h"
|
||||
#include "sha512.h"
|
||||
|
||||
/*
|
||||
* Arithmetic on twisted Edwards curve y^2 - x^2 = 1 + dx^2y^2
|
||||
* with d = -(121665/121666) mod p
|
||||
* d = 0x52036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978A3
|
||||
* p = 2**255 - 19
|
||||
* p = 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
|
||||
* Base point: y=4/5 mod p
|
||||
* x = 0x216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A
|
||||
* y = 0x6666666666666666666666666666666666666666666666666666666666666658
|
||||
* Base point order:
|
||||
* l = 2**252 + 27742317777372353535851937790883648493
|
||||
* l = 0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED
|
||||
*/
|
||||
|
||||
extern const U_WORD _w_maxP[K_WORDS];
|
||||
extern const U_WORD _w_NxBPO[16][K_WORDS];
|
||||
|
||||
#define _w_BPO _w_NxBPO[1]
|
||||
|
||||
/*
|
||||
// -- custom blind ---------------------------------------------------------
|
||||
//
|
||||
// edp_custom_blinding is defined in source/custom_blind.c
|
||||
// source/custom_blind is created randomly on every new build
|
||||
//
|
||||
// -------------------------------------------------------------------------
|
||||
*/
|
||||
extern EDP_BLINDING_CTX edp_custom_blinding;
|
||||
|
||||
const U_WORD _w_2d[K_WORDS] = /* 2*d */
|
||||
W256(0x26B2F159,0xEBD69B94,0x8283B156,0x00E0149A,0xEEF3D130,0x198E80F2,0x56DFFCE7,0x2406D9DC);
|
||||
const U_WORD _w_di[K_WORDS] = /* 1/d */
|
||||
W256(0xCDC9F843,0x25E0F276,0x4279542E,0x0B5DD698,0xCDB9CF66,0x2B162114,0x14D5CE43,0x40907ED2);
|
||||
|
||||
#include "base_folding8.h"
|
||||
|
||||
/*
|
||||
Reference: http://eprint.iacr.org/2008/522
|
||||
Cost: 7M + 7add
|
||||
Return: R = P + BasePoint
|
||||
*/
|
||||
void edp_AddBasePoint(Ext_POINT *p)
|
||||
{
|
||||
U_WORD a[K_WORDS], b[K_WORDS], c[K_WORDS], d[K_WORDS], e[K_WORDS];
|
||||
|
||||
ecp_SubReduce(a, p->y, p->x); /* A = (Y1-X1)*(Y2-X2) */
|
||||
ecp_MulReduce(a, a, _w_base_folding8[1].YmX);
|
||||
ecp_AddReduce(b, p->y, p->x); /* B = (Y1+X1)*(Y2+X2) */
|
||||
ecp_MulReduce(b, b, _w_base_folding8[1].YpX);
|
||||
ecp_MulReduce(c, p->t, _w_base_folding8[1].T2d); /* C = T1*2d*T2 */
|
||||
ecp_AddReduce(d, p->z, p->z); /* D = 2*Z1 */
|
||||
ecp_SubReduce(e, b, a); /* E = B-A */
|
||||
ecp_AddReduce(b, b, a); /* H = B+A */
|
||||
ecp_SubReduce(a, d, c); /* F = D-C */
|
||||
ecp_AddReduce(d, d, c); /* G = D+C */
|
||||
|
||||
ecp_MulReduce(p->x, e, a); /* E*F */
|
||||
ecp_MulReduce(p->y, b, d); /* H*G */
|
||||
ecp_MulReduce(p->t, e, b); /* E*H */
|
||||
ecp_MulReduce(p->z, d, a); /* G*F */
|
||||
}
|
||||
|
||||
/*
|
||||
Assumptions: pre-computed q, q->Z=1
|
||||
Cost: 7M + 7add
|
||||
Return: P = P + Q
|
||||
*/
|
||||
void edp_AddAffinePoint(Ext_POINT *p, const PA_POINT *q)
|
||||
{
|
||||
U_WORD a[K_WORDS], b[K_WORDS], c[K_WORDS], d[K_WORDS], e[K_WORDS];
|
||||
ecp_SubReduce(a, p->y, p->x); /* A = (Y1-X1)*(Y2-X2) */
|
||||
ecp_MulReduce(a, a, q->YmX);
|
||||
ecp_AddReduce(b, p->y, p->x); /* B = (Y1+X1)*(Y2+X2) */
|
||||
ecp_MulReduce(b, b, q->YpX);
|
||||
ecp_MulReduce(c, p->t, q->T2d); /* C = T1*2d*T2 */
|
||||
ecp_AddReduce(d, p->z, p->z); /* D = Z1*2*Z2 (Z2=1)*/
|
||||
ecp_SubReduce(e, b, a); /* E = B-A */
|
||||
ecp_AddReduce(b, b, a); /* H = B+A */
|
||||
ecp_SubReduce(a, d, c); /* F = D-C */
|
||||
ecp_AddReduce(d, d, c); /* G = D+C */
|
||||
|
||||
ecp_MulReduce(p->x, e, a); /* E*F */
|
||||
ecp_MulReduce(p->y, b, d); /* H*G */
|
||||
ecp_MulReduce(p->t, e, b); /* E*H */
|
||||
ecp_MulReduce(p->z, d, a); /* G*F */
|
||||
}
|
||||
|
||||
/*
|
||||
Reference: http://eprint.iacr.org/2008/522
|
||||
Cost: 4M + 4S + 7add
|
||||
Return: P = 2*P
|
||||
*/
|
||||
void edp_DoublePoint(Ext_POINT *p)
|
||||
{
|
||||
U_WORD a[K_WORDS], b[K_WORDS], c[K_WORDS], d[K_WORDS], e[K_WORDS];
|
||||
|
||||
ecp_SqrReduce(a, p->x); /* A = X1^2 */
|
||||
ecp_SqrReduce(b, p->y); /* B = Y1^2 */
|
||||
ecp_SqrReduce(c, p->z); /* C = 2*Z1^2 */
|
||||
ecp_AddReduce(c, c, c);
|
||||
ecp_SubReduce(d, _w_maxP, a); /* D = -A */
|
||||
|
||||
ecp_SubReduce(a, d, b); /* H = D-B */
|
||||
ecp_AddReduce(d, d, b); /* G = D+B */
|
||||
ecp_SubReduce(b, d, c); /* F = G-C */
|
||||
ecp_AddReduce(e, p->x, p->y); /* E = (X1+Y1)^2-A-B = (X1+Y1)^2+H */
|
||||
ecp_SqrReduce(e, e);
|
||||
ecp_AddReduce(e, e, a);
|
||||
|
||||
ecp_MulReduce(p->x, e, b); /* E*F */
|
||||
ecp_MulReduce(p->y, a, d); /* H*G */
|
||||
ecp_MulReduce(p->z, d, b); /* G*F */
|
||||
ecp_MulReduce(p->t, e, a); /* E*H */
|
||||
}
|
||||
|
||||
/* -- FOLDING ---------------------------------------------------------------
|
||||
//
|
||||
// The performance boost is achieved by a process that I call it FOLDING.
|
||||
// Folding can be viewed as an extension of Shamir's trick but it is based
|
||||
// on break down of the scalar multiplier of a*P into a polynomial of the
|
||||
// form:
|
||||
//
|
||||
// a*P = SUM(a_i*2^(i*w))*P for i = 0,1,2,...n-1
|
||||
//
|
||||
// a*P = SUM(a_i*P_i)
|
||||
//
|
||||
// where P_i = (2^(i*w))*P
|
||||
// n = number of folds
|
||||
// w = bit-length of a_i
|
||||
//
|
||||
// For folding of 8, 256-bit multiplier 'a' is chopped into 8 limbs of
|
||||
// 32-bits each (a_0, a_1,...a_7). P_0 - P_7 can be pre-calculated and
|
||||
// their 256-different permutations can be cached or hard-coded
|
||||
// directly into the code.
|
||||
// This arrangement combined with double-and-add approach reduces the
|
||||
// number of EC point calculations by a factor of 8. We only need 31
|
||||
// double & add operations.
|
||||
//
|
||||
// +---+---+---+---+---+---+- .... -+---+---+---+---+---+---+
|
||||
// a = (|255|254|253|252|251|250| | 5 | 4 | 3 | 2 | 1 | 0 |)
|
||||
// +---+---+---+---+---+---+- .... -+---+---+---+---+---+---+
|
||||
//
|
||||
// a_i P_i
|
||||
// +---+---+---+ .... -+---+---+---+ ----------
|
||||
// a7 = (|255|254|253| |226|225|224|) * (2**224)*P
|
||||
// +---+---+---+ .... -+---+---+---+
|
||||
// a6 = (|225|224|223| |194|193|192|) * (2**192)*P
|
||||
// +---+---+---+ .... -+---+---+---+
|
||||
// a5 = (|191|190|189| |162|161|160|) * (2**160)*P
|
||||
// +---+---+---+ .... -+---+---+---+
|
||||
// a4 = (|159|158|157| |130|129|128|) * (2**128)*P
|
||||
// +---+---+---+ .... -+---+---+---+
|
||||
// a3 = (|127|126|125| | 98| 97| 96|) * (2**96)*P
|
||||
// +---+---+---+ .... -+---+---+---+
|
||||
// a2 = (| 95| 94| 93| | 66| 65| 64|) * (2**64)*P
|
||||
// +---+---+---+ .... -+---+---+---+
|
||||
// a1 = (| 63| 62| 61| | 34| 33| 32|) * (2**32)*P
|
||||
// +---+---+---+ .... -+---+---+---+
|
||||
// a0 = (| 31| 30| 29| | 2 | 1 | 0 |) * (2**0)*P
|
||||
// +---+---+---+ .... -+---+---+---+
|
||||
// | | | |
|
||||
// | +--+ | +--+
|
||||
// | | | |
|
||||
// V V slices V V
|
||||
// +---+ +---+ .... +---+ +---+
|
||||
// |255| |254| |225| |224| P7
|
||||
// +---+ +---+ .... +---+ +---+
|
||||
// |225| |224| |193| |192| P6
|
||||
// +---+ +---+ .... +---+ +---+
|
||||
// |191| |190| |161| |160| P5
|
||||
// +---+ +---+ .... +---+ +---+
|
||||
// |159| |158| |129| |128| P4
|
||||
// +---+ +---+ .... +---+ +---+
|
||||
// |127| |126| | 97| | 96| P3
|
||||
// +---+ +---+ .... +---+ +---+
|
||||
// | 95| | 94| | 65| | 64| P2
|
||||
// +---+ +---+ .... +---+ +---+
|
||||
// | 63| | 62| | 33| | 32| P1
|
||||
// +---+ +---+ .... +---+ +---+
|
||||
// | 31| | 30| | 1 | | 0 | P0
|
||||
// +---+ +---+ .... +---+ +---+
|
||||
// cut[]: 0 1 .... 30 31
|
||||
// --------------------------------------------------------------------------
|
||||
// Return S = a*P where P is ed25519 base point and R is random
|
||||
*/
|
||||
void edp_BasePointMult(
|
||||
OUT Ext_POINT *S,
|
||||
IN const U_WORD *sk,
|
||||
IN const U_WORD *R)
|
||||
{
|
||||
int i = 1;
|
||||
U8 cut[32];
|
||||
const PA_POINT *p0;
|
||||
|
||||
ecp_8Folds(cut, sk);
|
||||
|
||||
p0 = &_w_base_folding8[cut[0]];
|
||||
|
||||
ecp_SubReduce(S->x, p0->YpX, p0->YmX); /* 2x */
|
||||
ecp_AddReduce(S->y, p0->YpX, p0->YmX); /* 2y */
|
||||
ecp_MulReduce(S->t, p0->T2d, _w_di); /* 2xy */
|
||||
|
||||
/* Randomize starting point */
|
||||
|
||||
ecp_AddReduce(S->z, R, R); /* Z = 2R */
|
||||
ecp_MulReduce(S->x, S->x, R); /* X = 2xR */
|
||||
ecp_MulReduce(S->t, S->t, R); /* T = 2xyR */
|
||||
ecp_MulReduce(S->y, S->y, R); /* Y = 2yR */
|
||||
|
||||
do
|
||||
{
|
||||
edp_DoublePoint(S);
|
||||
edp_AddAffinePoint(S, &_w_base_folding8[cut[i]]);
|
||||
} while (i++ < 31);
|
||||
}
|
||||
|
||||
void edp_BasePointMultiply(
|
||||
OUT Affine_POINT *R,
|
||||
IN const U_WORD *sk,
|
||||
IN const void *blinding)
|
||||
{
|
||||
Ext_POINT S;
|
||||
U_WORD t[K_WORDS];
|
||||
|
||||
if (blinding)
|
||||
{
|
||||
eco_AddReduce(t, sk, ((EDP_BLINDING_CTX*)blinding)->bl);
|
||||
edp_BasePointMult(&S, t, ((EDP_BLINDING_CTX*)blinding)->zr);
|
||||
edp_AddPoint(&S, &S, &((EDP_BLINDING_CTX*)blinding)->BP);
|
||||
}
|
||||
else
|
||||
{
|
||||
edp_BasePointMult(&S, sk, edp_custom_blinding.zr);
|
||||
}
|
||||
|
||||
ecp_Inverse(S.z, S.z);
|
||||
ecp_MulMod(R->x, S.x, S.z);
|
||||
ecp_MulMod(R->y, S.y, S.z);
|
||||
}
|
||||
|
||||
void edp_ExtPoint2PE(PE_POINT *r, const Ext_POINT *p)
|
||||
{
|
||||
ecp_AddReduce(r->YpX, p->y, p->x);
|
||||
ecp_SubReduce(r->YmX, p->y, p->x);
|
||||
ecp_MulReduce(r->T2d, p->t, _w_2d);
|
||||
ecp_AddReduce(r->Z2, p->z, p->z);
|
||||
}
|
||||
|
||||
/* -- Blinding -------------------------------------------------------------
|
||||
//
|
||||
// Blinding is a measure to protect against side channel attacks.
|
||||
// Blinding randomizes the scalar multiplier.
|
||||
//
|
||||
// Instead of calculating a*P, calculate (a+b mod BPO)*P + B
|
||||
//
|
||||
// Where b = random blinding and B = -b*P
|
||||
//
|
||||
// -------------------------------------------------------------------------
|
||||
*/
|
||||
void *ed25519_Blinding_Init(
|
||||
void *context, /* IO: null or ptr blinding context */
|
||||
const unsigned char *seed, /* IN: [size bytes] random blinding seed */
|
||||
size_t size) /* IN: size of blinding seed */
|
||||
{
|
||||
struct {
|
||||
Ext_POINT T;
|
||||
U_WORD t[K_WORDS];
|
||||
SHA512_CTX H;
|
||||
U8 digest[SHA512_DIGEST_LENGTH];
|
||||
} d;
|
||||
|
||||
EDP_BLINDING_CTX *ctx = (EDP_BLINDING_CTX*)context;
|
||||
|
||||
if (ctx == 0)
|
||||
{
|
||||
ctx = (EDP_BLINDING_CTX*)mem_alloc(sizeof(EDP_BLINDING_CTX));
|
||||
if (ctx == 0) return 0;
|
||||
}
|
||||
|
||||
/* Use edp_custom_blinding to protect generation of the new blinder */
|
||||
|
||||
SHA512_Init(&d.H);
|
||||
SHA512_Update(&d.H, edp_custom_blinding.zr, 32);
|
||||
SHA512_Update(&d.H, seed, size);
|
||||
SHA512_Final(d.digest, &d.H);
|
||||
|
||||
ecp_BytesToWords(ctx->zr, d.digest+32);
|
||||
ecp_BytesToWords(d.t, d.digest);
|
||||
eco_Mod(d.t);
|
||||
ecp_Sub(ctx->bl, _w_BPO, d.t);
|
||||
|
||||
eco_AddReduce(d.t, d.t, edp_custom_blinding.bl);
|
||||
edp_BasePointMult(&d.T, d.t, edp_custom_blinding.zr);
|
||||
edp_AddPoint(&d.T, &d.T, &edp_custom_blinding.BP);
|
||||
|
||||
edp_ExtPoint2PE(&ctx->BP, &d.T);
|
||||
|
||||
/* clear potentially sensitive data */
|
||||
mem_clear (&d, sizeof(d));
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void ed25519_Blinding_Finish(
|
||||
void *context) /* IN: blinding context */
|
||||
{
|
||||
if (context)
|
||||
{
|
||||
mem_clear (context, sizeof(EDP_BLINDING_CTX));
|
||||
mem_free (context);
|
||||
}
|
||||
}
|
||||
|
||||
/* Generate public and private key pair associated with the secret key */
|
||||
void ed25519_CreateKeyPair(
|
||||
unsigned char *pubKey, /* OUT: public key */
|
||||
unsigned char *privKey, /* OUT: private key */
|
||||
const void *blinding, /* IN: [optional] null or blinding context */
|
||||
const unsigned char *sk) /* IN: secret key (32 bytes) */
|
||||
{
|
||||
U8 md[SHA512_DIGEST_LENGTH];
|
||||
U_WORD t[K_WORDS];
|
||||
SHA512_CTX H;
|
||||
Affine_POINT Q;
|
||||
|
||||
/* [a:b] = H(sk) */
|
||||
SHA512_Init(&H);
|
||||
SHA512_Update(&H, sk, 32);
|
||||
SHA512_Final(md, &H);
|
||||
ecp_TrimSecretKey(md);
|
||||
|
||||
ecp_BytesToWords(t, md);
|
||||
edp_BasePointMultiply(&Q, t, blinding);
|
||||
ed25519_PackPoint(pubKey, Q.y, Q.x[0]);
|
||||
|
||||
memcpy(privKey, sk, 32);
|
||||
memcpy(privKey+32, pubKey, 32);
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate message signature
|
||||
*/
|
||||
void ed25519_SignMessage(
|
||||
unsigned char *signature, /* OUT: [64 bytes] signature (R,S) */
|
||||
const unsigned char *privKey, /* IN: [64 bytes] private key (sk,pk) */
|
||||
const void *blinding, /* IN: [optional] null or blinding context */
|
||||
const unsigned char *msg, /* IN: [msg_size bytes] message to sign */
|
||||
size_t msg_size)
|
||||
{
|
||||
SHA512_CTX H;
|
||||
Affine_POINT R;
|
||||
U_WORD a[K_WORDS], t[K_WORDS], r[K_WORDS];
|
||||
U8 md[SHA512_DIGEST_LENGTH];
|
||||
|
||||
/* [a:b] = H(sk) */
|
||||
SHA512_Init(&H);
|
||||
SHA512_Update(&H, privKey, 32);
|
||||
SHA512_Final(md, &H);
|
||||
ecp_TrimSecretKey(md); /* a = first 32 bytes */
|
||||
ecp_BytesToWords(a, md);
|
||||
|
||||
/* r = H(b + m) mod BPO */
|
||||
SHA512_Init(&H);
|
||||
SHA512_Update(&H, md+32, 32);
|
||||
SHA512_Update(&H, msg, msg_size);
|
||||
SHA512_Final(md, &H);
|
||||
eco_DigestToWords(r, md);
|
||||
eco_Mod(r); /* r mod BPO */
|
||||
|
||||
/* R = r*P */
|
||||
edp_BasePointMultiply(&R, r, blinding);
|
||||
ed25519_PackPoint(signature, R.y, R.x[0]); /* R part of signature */
|
||||
|
||||
/* S = r + H(encoded(R) + pk + m) * a mod BPO */
|
||||
SHA512_Init(&H);
|
||||
SHA512_Update(&H, signature, 32); /* encoded(R) */
|
||||
SHA512_Update(&H, privKey+32, 32); /* pk */
|
||||
SHA512_Update(&H, msg, msg_size); /* m */
|
||||
SHA512_Final(md, &H);
|
||||
eco_DigestToWords(t, md);
|
||||
|
||||
eco_MulReduce(t, t, a); /* h()*a */
|
||||
eco_AddReduce(t, t, r);
|
||||
eco_Mod(t);
|
||||
ecp_WordsToBytes(signature+32, t); /* S part of signature */
|
||||
|
||||
/* Clear sensitive data */
|
||||
ecp_SetValue(a, 0);
|
||||
ecp_SetValue(r, 0);
|
||||
}
|
313
source/extern/curve25519/source/ed25519_verify.c
vendored
Normal file
313
source/extern/curve25519/source/ed25519_verify.c
vendored
Normal file
@ -0,0 +1,313 @@
|
||||
/* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 mehdi sotoodeh
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "../include/external_calls.h"
|
||||
#include "curve25519_mehdi.h"
|
||||
#include "../include/ed25519_signature.h"
|
||||
#include "sha512.h"
|
||||
|
||||
/*
|
||||
* Arithmetic on twisted Edwards curve y^2 - x^2 = 1 + dx^2y^2
|
||||
* with d = -(121665/121666) mod p
|
||||
* d = 0x52036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978A3
|
||||
* p = 2**255 - 19
|
||||
* p = 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
|
||||
* Base point: y=4/5 mod p
|
||||
* x = 0x216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A
|
||||
* y = 0x6666666666666666666666666666666666666666666666666666666666666658
|
||||
* Base point order:
|
||||
* l = 2**252 + 27742317777372353535851937790883648493
|
||||
* l = 0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
unsigned char pk[32];
|
||||
PE_POINT q_table[16];
|
||||
} EDP_SIGV_CTX;
|
||||
|
||||
extern const U_WORD _w_P[K_WORDS];
|
||||
extern const U_WORD _w_di[K_WORDS];
|
||||
|
||||
extern const PA_POINT _w_base_folding8[256];
|
||||
extern const U_WORD _w_NxBPO[16][K_WORDS];
|
||||
|
||||
#define _w_BPO _w_NxBPO[1]
|
||||
|
||||
#define _w_Zero _w_base_folding8[0].T2d
|
||||
#define _w_One _w_base_folding8[0].YpX
|
||||
|
||||
const U_WORD _w_I[K_WORDS] = /* sqrt(-1) */
|
||||
W256(0x4A0EA0B0,0xC4EE1B27,0xAD2FE478,0x2F431806,0x3DFBD7A7,0x2B4D0099,0x4FC1DF0B,0x2B832480);
|
||||
|
||||
static const U_WORD _w_d[K_WORDS] =
|
||||
W256(0x135978A3,0x75EB4DCA,0x4141D8AB,0x00700A4D,0x7779E898,0x8CC74079,0x2B6FFE73,0x52036CEE);
|
||||
|
||||
void ed25519_CalculateX(OUT U_WORD *X, IN const U_WORD *Y, U_WORD parity)
|
||||
{
|
||||
U_WORD u[K_WORDS], v[K_WORDS], a[K_WORDS], b[K_WORDS];
|
||||
|
||||
/* Calculate sqrt((y^2 - 1)/(d*y^2 + 1)) */
|
||||
|
||||
ecp_SqrReduce(u, Y); /* u = y^2 */
|
||||
ecp_MulReduce(v, u, _w_d); /* v = dy^2 */
|
||||
ecp_SubReduce(u, u, _w_One); /* u = y^2-1 */
|
||||
ecp_AddReduce(v, v, _w_One); /* v = dy^2+1 */
|
||||
|
||||
/* Calculate: sqrt(u/v) = u*v^3 * (u*v^7)^((p-5)/8) */
|
||||
|
||||
ecp_SqrReduce(b, v);
|
||||
ecp_MulReduce(a, u, b);
|
||||
ecp_MulReduce(a, a, v); /* a = u*v^3 */
|
||||
ecp_SqrReduce(b, b); /* b = v^4 */
|
||||
ecp_MulReduce(b, a, b); /* b = u*v^7 */
|
||||
ecp_ModExp2523(b, b);
|
||||
ecp_MulReduce(X, b, a);
|
||||
|
||||
/* Check if we have correct sqrt, else, multiply by sqrt(-1) */
|
||||
|
||||
ecp_SqrReduce(b, X);
|
||||
ecp_MulReduce(b, b, v);
|
||||
ecp_SubReduce(b, b, u);
|
||||
ecp_Mod(b);
|
||||
if (ecp_CmpNE(b, _w_Zero)) ecp_MulReduce(X, X, _w_I);
|
||||
|
||||
while (ecp_CmpLT(X, _w_P) == 0) ecp_Sub(X, X, _w_P);
|
||||
|
||||
/* match parity */
|
||||
if (((X[0] ^ parity) & 1) != 0)
|
||||
ecp_Sub(X, _w_P, X);
|
||||
}
|
||||
|
||||
void ed25519_UnpackPoint(Affine_POINT *r, const unsigned char *p)
|
||||
{
|
||||
U8 parity = ecp_DecodeInt(r->y, p);
|
||||
ed25519_CalculateX(r->x, r->y, parity);
|
||||
}
|
||||
|
||||
void ecp_SrqMulReduce(U_WORD *Z, const U_WORD *X, int n, const U_WORD *Y)
|
||||
{
|
||||
U_WORD t[K_WORDS];
|
||||
ecp_SqrReduce(t, X);
|
||||
while (n-- > 1) ecp_SqrReduce(t, t);
|
||||
ecp_MulReduce(Z, t, Y);
|
||||
}
|
||||
|
||||
void ecp_ModExp2523(U_WORD *Y, const U_WORD *X)
|
||||
{
|
||||
U_WORD x2[K_WORDS], x9[K_WORDS], x11[K_WORDS], x5[K_WORDS], x10[K_WORDS];
|
||||
U_WORD x20[K_WORDS], x50[K_WORDS], x100[K_WORDS], t[K_WORDS];
|
||||
|
||||
ecp_SqrReduce(x2, X); /* 2 */
|
||||
ecp_SrqMulReduce(x9, x2, 2, X); /* 9 */
|
||||
ecp_MulReduce(x11, x9, x2); /* 11 */
|
||||
ecp_SqrReduce(t, x11); /* 22 */
|
||||
ecp_MulReduce(x5, t, x9); /* 31 = 2^5 - 2^0 */
|
||||
ecp_SrqMulReduce(x10, x5, 5, x5); /* 2^10 - 2^0 */
|
||||
ecp_SrqMulReduce(x20, x10, 10, x10); /* 2^20 - 2^0 */
|
||||
ecp_SrqMulReduce(t, x20, 20, x20); /* 2^40 - 2^0 */
|
||||
ecp_SrqMulReduce(x50, t, 10, x10); /* 2^50 - 2^0 */
|
||||
ecp_SrqMulReduce(x100, x50, 50, x50); /* 2^100 - 2^0 */
|
||||
ecp_SrqMulReduce(t, x100, 100, x100); /* 2^200 - 2^0 */
|
||||
ecp_SrqMulReduce(t, t, 50, x50); /* 2^250 - 2^0 */
|
||||
ecp_SqrReduce(t, t); ecp_SqrReduce(t, t); /* 2^252 - 2^2 */
|
||||
ecp_MulReduce(Y, t, X); /* 2^252 - 3 */
|
||||
}
|
||||
|
||||
/*
|
||||
Assumptions: pre-computed q
|
||||
Cost: 8M + 6add
|
||||
Return: P = P + Q
|
||||
*/
|
||||
void edp_AddPoint(Ext_POINT *r, const Ext_POINT *p, const PE_POINT *q)
|
||||
{
|
||||
U_WORD a[K_WORDS], b[K_WORDS], c[K_WORDS], d[K_WORDS], e[K_WORDS];
|
||||
|
||||
ecp_SubReduce(a, p->y, p->x); /* A = (Y1-X1)*(Y2-X2) */
|
||||
ecp_MulReduce(a, a, q->YmX);
|
||||
ecp_AddReduce(b, p->y, p->x); /* B = (Y1+X1)*(Y2+X2) */
|
||||
ecp_MulReduce(b, b, q->YpX);
|
||||
ecp_MulReduce(c, p->t, q->T2d); /* C = T1*2d*T2 */
|
||||
ecp_MulReduce(d, p->z, q->Z2); /* D = Z1*2*Z2 */
|
||||
ecp_SubReduce(e, b, a); /* E = B-A */
|
||||
ecp_AddReduce(b, b, a); /* H = B+A */
|
||||
ecp_SubReduce(a, d, c); /* F = D-C */
|
||||
ecp_AddReduce(d, d, c); /* G = D+C */
|
||||
|
||||
ecp_MulReduce(r->x, e, a); /* E*F */
|
||||
ecp_MulReduce(r->y, b, d); /* H*G */
|
||||
ecp_MulReduce(r->t, e, b); /* E*H */
|
||||
ecp_MulReduce(r->z, d, a); /* G*F */
|
||||
}
|
||||
|
||||
int ed25519_VerifySignature(
|
||||
const unsigned char *signature, /* IN: signature (R,S) */
|
||||
const unsigned char *publicKey, /* IN: public key */
|
||||
const unsigned char *msg, size_t msg_size) /* IN: message to sign */
|
||||
{
|
||||
EDP_SIGV_CTX ctx;
|
||||
|
||||
ed25519_Verify_Init(&ctx, publicKey);
|
||||
|
||||
return ed25519_Verify_Check(&ctx, signature, msg, msg_size);
|
||||
}
|
||||
|
||||
#define QTABLE_SET(d,s) \
|
||||
edp_AddPoint(&T, &Q, &ctx->q_table[s]); \
|
||||
edp_ExtPoint2PE(&ctx->q_table[d], &T)
|
||||
|
||||
void * ed25519_Verify_Init(
|
||||
void *context, /* IO: null or context buffer to use */
|
||||
const unsigned char *publicKey) /* IN: [32 bytes] public key */
|
||||
{
|
||||
int i;
|
||||
Ext_POINT Q, T;
|
||||
EDP_SIGV_CTX *ctx = (EDP_SIGV_CTX*)context;
|
||||
|
||||
if (ctx == 0) ctx = (EDP_SIGV_CTX*)mem_alloc(sizeof(EDP_SIGV_CTX));
|
||||
|
||||
if (ctx)
|
||||
{
|
||||
memcpy(ctx->pk, publicKey, 32);
|
||||
i = ecp_DecodeInt(Q.y, publicKey);
|
||||
ed25519_CalculateX(Q.x, Q.y, ~i); /* Invert parity for -Q */
|
||||
ecp_MulMod(Q.t, Q.x, Q.y);
|
||||
ecp_SetValue(Q.z, 1);
|
||||
|
||||
/* pre-compute q-table */
|
||||
|
||||
/* Calculate: Q0=Q, Q1=(2^64)*Q, Q2=(2^128)*Q, Q3=(2^192)*Q */
|
||||
|
||||
ecp_SetValue(ctx->q_table[0].YpX, 1); /* -- -- -- -- */
|
||||
ecp_SetValue(ctx->q_table[0].YmX, 1);
|
||||
ecp_SetValue(ctx->q_table[0].T2d, 0);
|
||||
ecp_SetValue(ctx->q_table[0].Z2, 2);
|
||||
|
||||
edp_ExtPoint2PE(&ctx->q_table[1], &Q); /* -- -- -- q0 */
|
||||
|
||||
for (i = 0; i < 64; i++) edp_DoublePoint(&Q);
|
||||
|
||||
edp_ExtPoint2PE(&ctx->q_table[2], &Q); /* -- -- q1 -- */
|
||||
QTABLE_SET(3,1); /* -- -- q1 q0 */
|
||||
|
||||
do edp_DoublePoint(&Q); while (++i < 128);
|
||||
|
||||
edp_ExtPoint2PE(&ctx->q_table[4], &Q); /* -- q2 -- -- */
|
||||
QTABLE_SET(5, 1); /* -- q2 -- q0 */
|
||||
QTABLE_SET(6, 2); /* -- q2 q1 -- */
|
||||
QTABLE_SET(7, 3); /* -- q2 q1 q0 */
|
||||
|
||||
do edp_DoublePoint(&Q); while (++i < 192);
|
||||
|
||||
edp_ExtPoint2PE(&ctx->q_table[8], &Q); /* q3 -- -- -- */
|
||||
QTABLE_SET(9, 1); /* q3 -- -- q0 */
|
||||
QTABLE_SET(10, 2); /* q3 -- q1 -- */
|
||||
QTABLE_SET(11, 3); /* q3 -- q1 q0 */
|
||||
QTABLE_SET(12, 4); /* q3 q2 -- -- */
|
||||
QTABLE_SET(13, 5); /* q3 q2 -- q0 */
|
||||
QTABLE_SET(14, 6); /* q3 q2 q1 -- */
|
||||
QTABLE_SET(15, 7); /* q3 q2 q1 q0 */
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void ed25519_Verify_Finish(void *ctx)
|
||||
{
|
||||
mem_free(ctx);
|
||||
}
|
||||
|
||||
/*
|
||||
Assumptions: qtable = pre-computed Q
|
||||
Calculate: point R = a*P + b*Q where P is base point
|
||||
*/
|
||||
static void edp_PolyPointMultiply(
|
||||
Affine_POINT *r,
|
||||
const U_WORD *a,
|
||||
const U_WORD *b,
|
||||
const PE_POINT *qtable)
|
||||
{
|
||||
int i = 1;
|
||||
Ext_POINT S;
|
||||
const PE_POINT *q0;
|
||||
U8 u[32], v[64];
|
||||
|
||||
ecp_8Folds(u, a);
|
||||
ecp_4Folds(v, b);
|
||||
|
||||
/* Set initial value of S */
|
||||
q0 = &qtable[v[0]];
|
||||
ecp_SubReduce(S.x, q0->YpX, q0->YmX); /* 2x */
|
||||
ecp_AddReduce(S.y, q0->YpX, q0->YmX); /* 2y */
|
||||
ecp_MulReduce(S.t, q0->T2d, _w_di); /* 2xy */
|
||||
ecp_Copy(S.z, q0->Z2); /* 2z */
|
||||
|
||||
do
|
||||
{ /* 31D + 31A */
|
||||
edp_DoublePoint(&S);
|
||||
edp_AddPoint(&S, &S, &qtable[v[i]]);
|
||||
} while (++i < 32);
|
||||
|
||||
do
|
||||
{ /* 32D + 64A */
|
||||
edp_DoublePoint(&S);
|
||||
edp_AddAffinePoint(&S, &_w_base_folding8[u[i-32]]);
|
||||
edp_AddPoint(&S, &S, &qtable[v[i]]);
|
||||
} while (++i < 64);
|
||||
|
||||
ecp_Inverse(S.z, S.z);
|
||||
ecp_MulMod(r->x, S.x, S.z);
|
||||
ecp_MulMod(r->y, S.y, S.z);
|
||||
}
|
||||
|
||||
/*
|
||||
This function can be used for batch verification.
|
||||
Assumptions: context = ed25519_Verify_Init(pk)
|
||||
|
||||
*/
|
||||
int ed25519_Verify_Check(
|
||||
const void *context, /* IN: precomputes */
|
||||
const unsigned char *signature, /* IN: signature (R,S) */
|
||||
const unsigned char *msg, size_t msg_size) /* IN: message to sign */
|
||||
{
|
||||
SHA512_CTX H;
|
||||
Affine_POINT T;
|
||||
U_WORD h[K_WORDS], s[K_WORDS];
|
||||
U8 md[SHA512_DIGEST_LENGTH];
|
||||
|
||||
/* h = H(enc(R) + pk + m) mod BPO */
|
||||
SHA512_Init(&H);
|
||||
SHA512_Update(&H, signature, 32); /* enc(R) */
|
||||
SHA512_Update(&H, ((EDP_SIGV_CTX*)context)->pk, 32);
|
||||
SHA512_Update(&H, msg, msg_size);
|
||||
SHA512_Final(md, &H);
|
||||
eco_DigestToWords(h, md);
|
||||
eco_Mod(h);
|
||||
|
||||
/* T = s*P + h*(-Q) = (s - h*a)*P = r*P = R */
|
||||
|
||||
ecp_BytesToWords(s, signature+32);
|
||||
edp_PolyPointMultiply(&T, s, h, ((EDP_SIGV_CTX*)context)->q_table);
|
||||
ed25519_PackPoint(md, T.y, T.x[0]);
|
||||
|
||||
return (memcmp(md, signature, 32) == 0) ? 1 : 0;
|
||||
}
|
294
source/extern/curve25519/source/sha512.c
vendored
Normal file
294
source/extern/curve25519/source/sha512.c
vendored
Normal file
@ -0,0 +1,294 @@
|
||||
/* crypto/sha/sha512.c */
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2004 The OpenSSL Project. All rights reserved
|
||||
* according to the OpenSSL license [found in ../../LICENSE].
|
||||
* ====================================================================
|
||||
*/
|
||||
/*
|
||||
* IMPLEMENTATION NOTES.
|
||||
*
|
||||
* As you might have noticed 32-bit hash algorithms:
|
||||
*
|
||||
* - permit SHA_LONG to be wider than 32-bit (case on CRAY);
|
||||
* - optimized versions implement two transform functions: one operating
|
||||
* on [aligned] data in host byte order and one - on data in input
|
||||
* stream byte order;
|
||||
* - share common byte-order neutral collector and padding function
|
||||
* implementations, ../md32_common.h;
|
||||
*
|
||||
* Neither of the above applies to this SHA-512 implementations. Reasons
|
||||
* [in reverse order] are:
|
||||
*
|
||||
* - it's the only 64-bit hash algorithm for the moment of this writing,
|
||||
* there is no need for common collector/padding implementation [yet];
|
||||
* - by supporting only one transform function [which operates on
|
||||
* *aligned* data in input stream byte order, big-endian in this case]
|
||||
* we minimize burden of maintenance in two ways: a) collector/padding
|
||||
* function is simpler; b) only one transform function to stare at;
|
||||
* - SHA_LONG64 is required to be exactly 64-bit in order to be able to
|
||||
* apply a number of optimizations to mitigate potential performance
|
||||
* penalties caused by previous design decision;
|
||||
*
|
||||
* Caveat lector.
|
||||
*
|
||||
* Implementation relies on the fact that "long long" is 64-bit on
|
||||
* both 32- and 64-bit platforms. If some compiler vendor comes up
|
||||
* with 128-bit long long, adjustment to sha.h would be required.
|
||||
* As this implementation relies on 64-bit integer type, it's totally
|
||||
* inappropriate for platforms which don't support it, most notably
|
||||
* 16-bit platforms.
|
||||
* <appro@fy.chalmers.se>
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "../include/external_calls.h"
|
||||
#include "sha512.h"
|
||||
|
||||
#define UINT64(X) X##ULL
|
||||
|
||||
void SHA512_Transform (SHA512_CTX *ctx, const void *in);
|
||||
|
||||
void SHA512_Init (SHA512_CTX *c)
|
||||
{
|
||||
c->h[0]=UINT64(0x6a09e667f3bcc908);
|
||||
c->h[1]=UINT64(0xbb67ae8584caa73b);
|
||||
c->h[2]=UINT64(0x3c6ef372fe94f82b);
|
||||
c->h[3]=UINT64(0xa54ff53a5f1d36f1);
|
||||
c->h[4]=UINT64(0x510e527fade682d1);
|
||||
c->h[5]=UINT64(0x9b05688c2b3e6c1f);
|
||||
c->h[6]=UINT64(0x1f83d9abfb41bd6b);
|
||||
c->h[7]=UINT64(0x5be0cd19137e2179);
|
||||
|
||||
c->Nl=0;
|
||||
c->Nh=0;
|
||||
c->num=0;
|
||||
c->md_len=SHA512_DIGEST_LENGTH;
|
||||
}
|
||||
|
||||
void SHA512_Final (unsigned char *md, SHA512_CTX *c)
|
||||
{
|
||||
unsigned char *p=(unsigned char *)c->u.p;
|
||||
size_t n=c->num;
|
||||
|
||||
p[n]=0x80; /* There always is a room for one */
|
||||
n++;
|
||||
if (n > (SHA512_CBLOCK-16))
|
||||
mem_fill (p+n,0,SHA512_CBLOCK-n), n=0,
|
||||
SHA512_Transform (c,p);
|
||||
|
||||
mem_fill (p+n,0,SHA512_CBLOCK-16-n);
|
||||
#ifdef ECP_CONFIG_BIG_ENDIAN
|
||||
c->u.d[SHA_LBLOCK-2] = c->Nh;
|
||||
c->u.d[SHA_LBLOCK-1] = c->Nl;
|
||||
#else
|
||||
p[SHA512_CBLOCK-1] = (unsigned char)(c->Nl);
|
||||
p[SHA512_CBLOCK-2] = (unsigned char)(c->Nl>>8);
|
||||
p[SHA512_CBLOCK-3] = (unsigned char)(c->Nl>>16);
|
||||
p[SHA512_CBLOCK-4] = (unsigned char)(c->Nl>>24);
|
||||
p[SHA512_CBLOCK-5] = (unsigned char)(c->Nl>>32);
|
||||
p[SHA512_CBLOCK-6] = (unsigned char)(c->Nl>>40);
|
||||
p[SHA512_CBLOCK-7] = (unsigned char)(c->Nl>>48);
|
||||
p[SHA512_CBLOCK-8] = (unsigned char)(c->Nl>>56);
|
||||
p[SHA512_CBLOCK-9] = (unsigned char)(c->Nh);
|
||||
p[SHA512_CBLOCK-10] = (unsigned char)(c->Nh>>8);
|
||||
p[SHA512_CBLOCK-11] = (unsigned char)(c->Nh>>16);
|
||||
p[SHA512_CBLOCK-12] = (unsigned char)(c->Nh>>24);
|
||||
p[SHA512_CBLOCK-13] = (unsigned char)(c->Nh>>32);
|
||||
p[SHA512_CBLOCK-14] = (unsigned char)(c->Nh>>40);
|
||||
p[SHA512_CBLOCK-15] = (unsigned char)(c->Nh>>48);
|
||||
p[SHA512_CBLOCK-16] = (unsigned char)(c->Nh>>56);
|
||||
#endif
|
||||
|
||||
SHA512_Transform (c,p);
|
||||
|
||||
if (md) for (n=0; n < SHA512_DIGEST_LENGTH/8; n++)
|
||||
{
|
||||
M64 m;
|
||||
m.u64 = c->h[n];
|
||||
*(md++) = m.u8.b7;
|
||||
*(md++) = m.u8.b6;
|
||||
*(md++) = m.u8.b5;
|
||||
*(md++) = m.u8.b4;
|
||||
*(md++) = m.u8.b3;
|
||||
*(md++) = m.u8.b2;
|
||||
*(md++) = m.u8.b1;
|
||||
*(md++) = m.u8.b0;
|
||||
}
|
||||
}
|
||||
|
||||
void SHA512_Update (SHA512_CTX *c, const void *_data, size_t len)
|
||||
{
|
||||
SHA_LONG64 l;
|
||||
unsigned char *p=c->u.p;
|
||||
const unsigned char *data=(const unsigned char *)_data;
|
||||
|
||||
if (len==0) return;
|
||||
|
||||
l = (c->Nl+(((SHA_LONG64)len)<<3))&UINT64(0xffffffffffffffff);
|
||||
if (l < c->Nl) c->Nh++;
|
||||
if (sizeof(len)>=8) c->Nh+=(((SHA_LONG64)len)>>61);
|
||||
c->Nl=l;
|
||||
|
||||
if (c->num != 0)
|
||||
{
|
||||
size_t n = SHA512_CBLOCK - c->num;
|
||||
|
||||
if (len < n)
|
||||
{
|
||||
memcpy (p+c->num,data,len), c->num += (unsigned int)len;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy (p+c->num,data,n), c->num = 0;
|
||||
len-=n, data+=n;
|
||||
SHA512_Transform (c,p);
|
||||
}
|
||||
}
|
||||
|
||||
while (len >= SHA512_CBLOCK)
|
||||
{
|
||||
SHA512_Transform (c,data);//,len/SHA512_CBLOCK),
|
||||
data += SHA512_CBLOCK;
|
||||
len -= SHA512_CBLOCK;
|
||||
}
|
||||
|
||||
if (len != 0)
|
||||
memcpy (p,data,len), c->num = (int)len;
|
||||
}
|
||||
|
||||
static const SHA_LONG64 K512[80] =
|
||||
{
|
||||
UINT64(0x428a2f98d728ae22),UINT64(0x7137449123ef65cd),
|
||||
UINT64(0xb5c0fbcfec4d3b2f),UINT64(0xe9b5dba58189dbbc),
|
||||
UINT64(0x3956c25bf348b538),UINT64(0x59f111f1b605d019),
|
||||
UINT64(0x923f82a4af194f9b),UINT64(0xab1c5ed5da6d8118),
|
||||
UINT64(0xd807aa98a3030242),UINT64(0x12835b0145706fbe),
|
||||
UINT64(0x243185be4ee4b28c),UINT64(0x550c7dc3d5ffb4e2),
|
||||
UINT64(0x72be5d74f27b896f),UINT64(0x80deb1fe3b1696b1),
|
||||
UINT64(0x9bdc06a725c71235),UINT64(0xc19bf174cf692694),
|
||||
UINT64(0xe49b69c19ef14ad2),UINT64(0xefbe4786384f25e3),
|
||||
UINT64(0x0fc19dc68b8cd5b5),UINT64(0x240ca1cc77ac9c65),
|
||||
UINT64(0x2de92c6f592b0275),UINT64(0x4a7484aa6ea6e483),
|
||||
UINT64(0x5cb0a9dcbd41fbd4),UINT64(0x76f988da831153b5),
|
||||
UINT64(0x983e5152ee66dfab),UINT64(0xa831c66d2db43210),
|
||||
UINT64(0xb00327c898fb213f),UINT64(0xbf597fc7beef0ee4),
|
||||
UINT64(0xc6e00bf33da88fc2),UINT64(0xd5a79147930aa725),
|
||||
UINT64(0x06ca6351e003826f),UINT64(0x142929670a0e6e70),
|
||||
UINT64(0x27b70a8546d22ffc),UINT64(0x2e1b21385c26c926),
|
||||
UINT64(0x4d2c6dfc5ac42aed),UINT64(0x53380d139d95b3df),
|
||||
UINT64(0x650a73548baf63de),UINT64(0x766a0abb3c77b2a8),
|
||||
UINT64(0x81c2c92e47edaee6),UINT64(0x92722c851482353b),
|
||||
UINT64(0xa2bfe8a14cf10364),UINT64(0xa81a664bbc423001),
|
||||
UINT64(0xc24b8b70d0f89791),UINT64(0xc76c51a30654be30),
|
||||
UINT64(0xd192e819d6ef5218),UINT64(0xd69906245565a910),
|
||||
UINT64(0xf40e35855771202a),UINT64(0x106aa07032bbd1b8),
|
||||
UINT64(0x19a4c116b8d2d0c8),UINT64(0x1e376c085141ab53),
|
||||
UINT64(0x2748774cdf8eeb99),UINT64(0x34b0bcb5e19b48a8),
|
||||
UINT64(0x391c0cb3c5c95a63),UINT64(0x4ed8aa4ae3418acb),
|
||||
UINT64(0x5b9cca4f7763e373),UINT64(0x682e6ff3d6b2b8a3),
|
||||
UINT64(0x748f82ee5defb2fc),UINT64(0x78a5636f43172f60),
|
||||
UINT64(0x84c87814a1f0ab72),UINT64(0x8cc702081a6439ec),
|
||||
UINT64(0x90befffa23631e28),UINT64(0xa4506cebde82bde9),
|
||||
UINT64(0xbef9a3f7b2c67915),UINT64(0xc67178f2e372532b),
|
||||
UINT64(0xca273eceea26619c),UINT64(0xd186b8c721c0c207),
|
||||
UINT64(0xeada7dd6cde0eb1e),UINT64(0xf57d4f7fee6ed178),
|
||||
UINT64(0x06f067aa72176fba),UINT64(0x0a637dc5a2c898a6),
|
||||
UINT64(0x113f9804bef90dae),UINT64(0x1b710b35131c471b),
|
||||
UINT64(0x28db77f523047d84),UINT64(0x32caab7b40c72493),
|
||||
UINT64(0x3c9ebe0a15c9bebc),UINT64(0x431d67c49c100d4c),
|
||||
UINT64(0x4cc5d4becb3e42b6),UINT64(0x597f299cfc657e2a),
|
||||
UINT64(0x5fcb6fab3ad6faec),UINT64(0x6c44198c4a475817)
|
||||
};
|
||||
|
||||
#define B(x,j) (((SHA_LONG64)(*(((const unsigned char *)(&x))+j)))<<((7-j)*8))
|
||||
#define PULL64(x) (B(x,0)|B(x,1)|B(x,2)|B(x,3)|B(x,4)|B(x,5)|B(x,6)|B(x,7))
|
||||
#define ROTR(x,s) (((x)>>s) | (x)<<(64-s))
|
||||
|
||||
#define Sigma0(x) (ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39))
|
||||
#define Sigma1(x) (ROTR((x),14) ^ ROTR((x),18) ^ ROTR((x),41))
|
||||
#define sigma0(x) (ROTR((x),1) ^ ROTR((x),8) ^ ((x)>>7))
|
||||
#define sigma1(x) (ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6))
|
||||
|
||||
#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
|
||||
#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
|
||||
|
||||
#define ROUND_00_15(i,a,b,c,d,e,f,g,h) do { \
|
||||
T1 += h + Sigma1(e) + Ch(e,f,g) + K512[i]; \
|
||||
h = Sigma0(a) + Maj(a,b,c); \
|
||||
d += T1; h += T1; } while (0)
|
||||
|
||||
#define ROUND_16_80(i,j,a,b,c,d,e,f,g,h,X) do { \
|
||||
s0 = X[(j+1)&0x0f]; s0 = sigma0(s0); \
|
||||
s1 = X[(j+14)&0x0f]; s1 = sigma1(s1); \
|
||||
T1 = X[(j)&0x0f] += s0 + s1 + X[(j+9)&0x0f]; \
|
||||
ROUND_00_15(i+j,a,b,c,d,e,f,g,h); } while (0)
|
||||
|
||||
void SHA512_Transform (SHA512_CTX *ctx, const void *in)
|
||||
{
|
||||
const SHA_LONG64 *W = (SHA_LONG64*)in;
|
||||
SHA_LONG64 a,b,c,d,e,f,g,h,s0,s1,T1;
|
||||
SHA_LONG64 X[16];
|
||||
int i;
|
||||
|
||||
a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3];
|
||||
e = ctx->h[4]; f = ctx->h[5]; g = ctx->h[6]; h = ctx->h[7];
|
||||
|
||||
#ifdef ECP_CONFIG_BIG_ENDIAN
|
||||
T1 = X[0] = W[0]; ROUND_00_15(0,a,b,c,d,e,f,g,h);
|
||||
T1 = X[1] = W[1]; ROUND_00_15(1,h,a,b,c,d,e,f,g);
|
||||
T1 = X[2] = W[2]; ROUND_00_15(2,g,h,a,b,c,d,e,f);
|
||||
T1 = X[3] = W[3]; ROUND_00_15(3,f,g,h,a,b,c,d,e);
|
||||
T1 = X[4] = W[4]; ROUND_00_15(4,e,f,g,h,a,b,c,d);
|
||||
T1 = X[5] = W[5]; ROUND_00_15(5,d,e,f,g,h,a,b,c);
|
||||
T1 = X[6] = W[6]; ROUND_00_15(6,c,d,e,f,g,h,a,b);
|
||||
T1 = X[7] = W[7]; ROUND_00_15(7,b,c,d,e,f,g,h,a);
|
||||
T1 = X[8] = W[8]; ROUND_00_15(8,a,b,c,d,e,f,g,h);
|
||||
T1 = X[9] = W[9]; ROUND_00_15(9,h,a,b,c,d,e,f,g);
|
||||
T1 = X[10] = W[10]; ROUND_00_15(10,g,h,a,b,c,d,e,f);
|
||||
T1 = X[11] = W[11]; ROUND_00_15(11,f,g,h,a,b,c,d,e);
|
||||
T1 = X[12] = W[12]; ROUND_00_15(12,e,f,g,h,a,b,c,d);
|
||||
T1 = X[13] = W[13]; ROUND_00_15(13,d,e,f,g,h,a,b,c);
|
||||
T1 = X[14] = W[14]; ROUND_00_15(14,c,d,e,f,g,h,a,b);
|
||||
T1 = X[15] = W[15]; ROUND_00_15(15,b,c,d,e,f,g,h,a);
|
||||
#else
|
||||
T1 = X[0] = PULL64(W[0]); ROUND_00_15(0,a,b,c,d,e,f,g,h);
|
||||
T1 = X[1] = PULL64(W[1]); ROUND_00_15(1,h,a,b,c,d,e,f,g);
|
||||
T1 = X[2] = PULL64(W[2]); ROUND_00_15(2,g,h,a,b,c,d,e,f);
|
||||
T1 = X[3] = PULL64(W[3]); ROUND_00_15(3,f,g,h,a,b,c,d,e);
|
||||
T1 = X[4] = PULL64(W[4]); ROUND_00_15(4,e,f,g,h,a,b,c,d);
|
||||
T1 = X[5] = PULL64(W[5]); ROUND_00_15(5,d,e,f,g,h,a,b,c);
|
||||
T1 = X[6] = PULL64(W[6]); ROUND_00_15(6,c,d,e,f,g,h,a,b);
|
||||
T1 = X[7] = PULL64(W[7]); ROUND_00_15(7,b,c,d,e,f,g,h,a);
|
||||
T1 = X[8] = PULL64(W[8]); ROUND_00_15(8,a,b,c,d,e,f,g,h);
|
||||
T1 = X[9] = PULL64(W[9]); ROUND_00_15(9,h,a,b,c,d,e,f,g);
|
||||
T1 = X[10] = PULL64(W[10]); ROUND_00_15(10,g,h,a,b,c,d,e,f);
|
||||
T1 = X[11] = PULL64(W[11]); ROUND_00_15(11,f,g,h,a,b,c,d,e);
|
||||
T1 = X[12] = PULL64(W[12]); ROUND_00_15(12,e,f,g,h,a,b,c,d);
|
||||
T1 = X[13] = PULL64(W[13]); ROUND_00_15(13,d,e,f,g,h,a,b,c);
|
||||
T1 = X[14] = PULL64(W[14]); ROUND_00_15(14,c,d,e,f,g,h,a,b);
|
||||
T1 = X[15] = PULL64(W[15]); ROUND_00_15(15,b,c,d,e,f,g,h,a);
|
||||
#endif
|
||||
|
||||
for (i=16;i<80;i+=16)
|
||||
{
|
||||
ROUND_16_80(i, 0,a,b,c,d,e,f,g,h,X);
|
||||
ROUND_16_80(i, 1,h,a,b,c,d,e,f,g,X);
|
||||
ROUND_16_80(i, 2,g,h,a,b,c,d,e,f,X);
|
||||
ROUND_16_80(i, 3,f,g,h,a,b,c,d,e,X);
|
||||
ROUND_16_80(i, 4,e,f,g,h,a,b,c,d,X);
|
||||
ROUND_16_80(i, 5,d,e,f,g,h,a,b,c,X);
|
||||
ROUND_16_80(i, 6,c,d,e,f,g,h,a,b,X);
|
||||
ROUND_16_80(i, 7,b,c,d,e,f,g,h,a,X);
|
||||
ROUND_16_80(i, 8,a,b,c,d,e,f,g,h,X);
|
||||
ROUND_16_80(i, 9,h,a,b,c,d,e,f,g,X);
|
||||
ROUND_16_80(i,10,g,h,a,b,c,d,e,f,X);
|
||||
ROUND_16_80(i,11,f,g,h,a,b,c,d,e,X);
|
||||
ROUND_16_80(i,12,e,f,g,h,a,b,c,d,X);
|
||||
ROUND_16_80(i,13,d,e,f,g,h,a,b,c,X);
|
||||
ROUND_16_80(i,14,c,d,e,f,g,h,a,b,X);
|
||||
ROUND_16_80(i,15,b,c,d,e,f,g,h,a,X);
|
||||
}
|
||||
|
||||
ctx->h[0] += a; ctx->h[1] += b; ctx->h[2] += c; ctx->h[3] += d;
|
||||
ctx->h[4] += e; ctx->h[5] += f; ctx->h[6] += g; ctx->h[7] += h;
|
||||
}
|
92
source/extern/curve25519/source/sha512.h
vendored
Normal file
92
source/extern/curve25519/source/sha512.h
vendored
Normal file
@ -0,0 +1,92 @@
|
||||
/* crypto/sha/sha512.h */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 AUTHOR 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.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#ifndef HEADER_SHA512_H
|
||||
#define HEADER_SHA512_H
|
||||
|
||||
#include "BaseTypes.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SHA512_DIGEST_LENGTH 64
|
||||
#define SHA512_CBLOCK 128 /* SHA-512 treats input data as a
|
||||
* contiguous array of 64 bit
|
||||
* wide big-endian values. */
|
||||
#define SHA_LONG64 U64
|
||||
|
||||
typedef struct SHA512state_st
|
||||
{
|
||||
SHA_LONG64 h[8];
|
||||
SHA_LONG64 Nl,Nh;
|
||||
union {
|
||||
SHA_LONG64 d[8];
|
||||
unsigned char p[SHA512_CBLOCK];
|
||||
} u;
|
||||
unsigned int num, md_len;
|
||||
} SHA512_CTX;
|
||||
|
||||
void SHA512_Init(SHA512_CTX *c);
|
||||
void SHA512_Update(SHA512_CTX *c, const void *data, size_t len);
|
||||
void SHA512_Final(unsigned char *md, SHA512_CTX *c);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user