зеркало из https://github.com/microsoft/FourQlib.git
Add hash to curve function
This commit is contained in:
Родитель
8482714790
Коммит
ff61f68050
|
@ -188,6 +188,7 @@ typedef enum {
|
|||
ECCRYPTO_ERROR_INVALID_PARAMETER, // 0x06
|
||||
ECCRYPTO_ERROR_SHARED_KEY, // 0x07
|
||||
ECCRYPTO_ERROR_SIGNATURE_VERIFICATION, // 0x08
|
||||
ECCRYPTO_ERROR_HASH_TO_CURVE, // 0x09
|
||||
ECCRYPTO_ERROR_END_OF_LIST
|
||||
} ECCRYPTO_STATUS;
|
||||
|
||||
|
@ -204,7 +205,8 @@ typedef enum {
|
|||
#define ECCRYPTO_MSG_ERROR_NO_MEMORY "ECCRYPTO_ERROR_NO_MEMORY"
|
||||
#define ECCRYPTO_MSG_ERROR_INVALID_PARAMETER "ECCRYPTO_ERROR_INVALID_PARAMETER"
|
||||
#define ECCRYPTO_MSG_ERROR_SHARED_KEY "ECCRYPTO_ERROR_SHARED_KEY"
|
||||
#define ECCRYPTO_MSG_ERROR_SIGNATURE_VERIFICATION "ECCRYPTO_ERROR_SIGNATURE_VERIFICATION"
|
||||
#define ECCRYPTO_MSG_ERROR_SIGNATURE_VERIFICATION "ECCRYPTO_ERROR_SIGNATURE_VERIFICATION"
|
||||
#define ECCRYPTO_MSG_ERROR_HASH_TO_CURVE "ECCRYPTO_ERROR_HASH_TO_CURVE"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -131,6 +131,14 @@ ECCRYPTO_STATUS KeyGeneration(unsigned char* SecretKey, unsigned char* PublicKey
|
|||
ECCRYPTO_STATUS SecretAgreement(const unsigned char* SecretKey, const unsigned char* PublicKey, unsigned char* SharedSecret);
|
||||
|
||||
|
||||
/**************** Public API for hashing to curve, 64-byte public keys ****************/
|
||||
|
||||
// Hash GF(p^2) element to a curve point
|
||||
// Input: GF(p^2) element
|
||||
// Output: point in affine coordinates with co-factor cleared
|
||||
ECCRYPTO_STATUS HashToCurve(f2elm_t r, point_t P);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
* Preprint available at http://eprint.iacr.org/2015/565.
|
||||
************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
#ifndef __FOURQ_PARAMS_H__
|
||||
#define __FOURQ_PARAMS_H__
|
||||
|
||||
|
@ -30,4 +31,22 @@ static const uint64_t Montgomery_Rprime[4] = { 0xC81DB8795FF3D621, 0x173EA5AAEA6
|
|||
static const uint64_t Montgomery_rprime[4] = { 0xE12FE5F079BC3929, 0xD75E78B8D1FCDCF3, 0xBCE409ED76B5DB21, 0xF32702FDAFC1C074 };
|
||||
|
||||
|
||||
// Constants for hash to FourQ function
|
||||
|
||||
#if (RADIX == 32)
|
||||
static felm_t con1 = { 6651107, 0, 4290264256, 2147483647 };
|
||||
static felm_t con2 = { 1725590130, 1719979744, 2225079900, 707200452 };
|
||||
static felm_t b0 = { 3738038324, 2664081113, 587564626, 1252475115 };
|
||||
static felm_t b1 = { 17, 0, 4294967284, 2147483647 };
|
||||
static felm_t A0 = { 1289, 0, 4294966384, 2147483647 };
|
||||
static felm_t A1 = { 1007904792, 2866591091, 4136083791, 1668973403 };
|
||||
#elif (RADIX == 64)
|
||||
static felm_t con1 = { 6651107ULL, 9223372036850072768ULL };
|
||||
static felm_t con2 = { 7387256751988042354ULL, 3037402815281497692ULL };
|
||||
static felm_t b0 = { 11442141257964318772ULL, 5379339658566403666ULL };
|
||||
static felm_t b1 = { 17ULL, 9223372036854775796ULL };
|
||||
static felm_t A0 = { 1289ULL, 9223372036854774896ULL };
|
||||
static felm_t A1 = { 12311914987857864728ULL, 7168186187914912079ULL };
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -21,7 +21,8 @@ Global
|
|||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{719F1A49-62B2-41E2-B500-40FAD83AB12A}.Debug|Win32.ActiveCfg = Release|Win32
|
||||
{719F1A49-62B2-41E2-B500-40FAD83AB12A}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{719F1A49-62B2-41E2-B500-40FAD83AB12A}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{719F1A49-62B2-41E2-B500-40FAD83AB12A}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{719F1A49-62B2-41E2-B500-40FAD83AB12A}.Debug|x64.Build.0 = Debug|x64
|
||||
{719F1A49-62B2-41E2-B500-40FAD83AB12A}.Generic|Win32.ActiveCfg = Generic|Win32
|
||||
|
@ -31,7 +32,8 @@ Global
|
|||
{719F1A49-62B2-41E2-B500-40FAD83AB12A}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{719F1A49-62B2-41E2-B500-40FAD83AB12A}.Release|x64.ActiveCfg = Release|x64
|
||||
{719F1A49-62B2-41E2-B500-40FAD83AB12A}.Release|x64.Build.0 = Release|x64
|
||||
{A6DB2ADB-C570-47D5-BAAA-06904D60C091}.Debug|Win32.ActiveCfg = Release|Win32
|
||||
{A6DB2ADB-C570-47D5-BAAA-06904D60C091}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{A6DB2ADB-C570-47D5-BAAA-06904D60C091}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{A6DB2ADB-C570-47D5-BAAA-06904D60C091}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{A6DB2ADB-C570-47D5-BAAA-06904D60C091}.Debug|x64.Build.0 = Debug|x64
|
||||
{A6DB2ADB-C570-47D5-BAAA-06904D60C091}.Generic|Win32.ActiveCfg = Generic|Win32
|
||||
|
@ -42,6 +44,7 @@ Global
|
|||
{A6DB2ADB-C570-47D5-BAAA-06904D60C091}.Release|x64.ActiveCfg = Release|x64
|
||||
{A6DB2ADB-C570-47D5-BAAA-06904D60C091}.Release|x64.Build.0 = Release|x64
|
||||
{47A9BC7F-1C7F-4BB3-B5D1-7AC7DDAC0E04}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{47A9BC7F-1C7F-4BB3-B5D1-7AC7DDAC0E04}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{47A9BC7F-1C7F-4BB3-B5D1-7AC7DDAC0E04}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{47A9BC7F-1C7F-4BB3-B5D1-7AC7DDAC0E04}.Debug|x64.Build.0 = Debug|x64
|
||||
{47A9BC7F-1C7F-4BB3-B5D1-7AC7DDAC0E04}.Generic|Win32.ActiveCfg = Generic|Win32
|
||||
|
@ -52,6 +55,7 @@ Global
|
|||
{47A9BC7F-1C7F-4BB3-B5D1-7AC7DDAC0E04}.Release|x64.ActiveCfg = Release|x64
|
||||
{47A9BC7F-1C7F-4BB3-B5D1-7AC7DDAC0E04}.Release|x64.Build.0 = Release|x64
|
||||
{D36D493E-EFD2-4FF1-8CAE-2D16EEA76CAC}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{D36D493E-EFD2-4FF1-8CAE-2D16EEA76CAC}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{D36D493E-EFD2-4FF1-8CAE-2D16EEA76CAC}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{D36D493E-EFD2-4FF1-8CAE-2D16EEA76CAC}.Debug|x64.Build.0 = Debug|x64
|
||||
{D36D493E-EFD2-4FF1-8CAE-2D16EEA76CAC}.Generic|Win32.ActiveCfg = Generic|Win32
|
||||
|
|
|
@ -86,7 +86,7 @@
|
|||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>__WINDOWS__; _X86_; _GENERIC_; USE_ENDO=true;</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
|
@ -213,8 +213,8 @@
|
|||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\AMD64\fp_x64.h">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Generic|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Generic|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\FourQ.h" />
|
||||
<ClInclude Include="..\..\FourQ_api.h" />
|
||||
|
@ -234,6 +234,7 @@
|
|||
<ClCompile Include="..\..\eccp2_core.c" />
|
||||
<ClCompile Include="..\..\eccp2_no_endo.c" />
|
||||
<ClCompile Include="..\..\FourQ_params.h" />
|
||||
<ClCompile Include="..\..\hash_to_curve.c" />
|
||||
<ClCompile Include="..\..\kex.c" />
|
||||
<ClCompile Include="..\..\schnorrq.c" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -24,9 +24,6 @@
|
|||
<ClInclude Include="..\..\generic\fp.h">
|
||||
<Filter>Header Files\generic</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\AMD64\fp_x64.h">
|
||||
<Filter>Header Files\x64</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\FourQ.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
|
@ -42,6 +39,9 @@
|
|||
<ClInclude Include="..\..\FourQ_api.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\AMD64\fp_x64.h">
|
||||
<Filter>Header Files\x64</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\eccp2.c">
|
||||
|
@ -71,5 +71,8 @@
|
|||
<ClCompile Include="..\..\..\sha512\sha512.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\hash_to_curve.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -94,7 +94,7 @@
|
|||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>__WINDOWS__; _X86_; _GENERIC_; USE_ENDO=true;</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
|
|
|
@ -94,7 +94,7 @@
|
|||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>__WINDOWS__; _X86_; _GENERIC_; USE_ENDO=true;</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
|
|
|
@ -95,7 +95,7 @@
|
|||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>__WINDOWS__; _X86_; _GENERIC_; USE_ENDO=true;</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
|
|
|
@ -228,6 +228,7 @@ const char* FourQ_get_error_message(ECCRYPTO_STATUS Status)
|
|||
{ECCRYPTO_ERROR_INVALID_PARAMETER, ECCRYPTO_MSG_ERROR_INVALID_PARAMETER},
|
||||
{ECCRYPTO_ERROR_SHARED_KEY, ECCRYPTO_MSG_ERROR_SHARED_KEY},
|
||||
{ECCRYPTO_ERROR_SIGNATURE_VERIFICATION, ECCRYPTO_MSG_ERROR_SIGNATURE_VERIFICATION},
|
||||
{ECCRYPTO_ERROR_HASH_TO_CURVE, ECCRYPTO_MSG_ERROR_HASH_TO_CURVE},
|
||||
};
|
||||
|
||||
if (Status >= ECCRYPTO_STATUS_TYPE_SIZE || mapping[Status].string == NULL) {
|
||||
|
|
|
@ -0,0 +1,237 @@
|
|||
/**********************************************************************************
|
||||
* FourQlib: a high-performance crypto library based on the elliptic curve FourQ
|
||||
*
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
*
|
||||
* Abstract: hash to FourQ
|
||||
***********************************************************************************/
|
||||
|
||||
#include "FourQ_internal.h"
|
||||
#include "FourQ_params.h"
|
||||
|
||||
|
||||
static digit_t fpeq1271(digit_t* a, digit_t* b)
|
||||
{ // Constant-time comparison of two field elements, ai=bi? : (0) equal, (-1) unequal
|
||||
digit_t c = 0;
|
||||
|
||||
for (unsigned int i = 0; i < NWORDS_FIELD; i++)
|
||||
c |= a[i] ^ b[i];
|
||||
|
||||
return (digit_t)((-(sdigit_t)(c >> 1) | -(sdigit_t)(c & 1)) >> (8*sizeof(digit_t) - 1));
|
||||
}
|
||||
|
||||
|
||||
static void fpselect(digit_t* a, digit_t* b, digit_t* c, digit_t selector)
|
||||
{ // Constant-time selection of field elements
|
||||
// If selector = 0 do c <- a, else if selector =-1 do c <- b
|
||||
|
||||
for (unsigned int i = 0; i < NWORDS_FIELD; i++)
|
||||
c[i] = (selector & (a[i] ^ b[i])) ^ a[i];
|
||||
}
|
||||
|
||||
|
||||
ECCRYPTO_STATUS HashToCurve(f2elm_t r, point_t out)
|
||||
{
|
||||
digit_t *r0 = (digit_t*)r[0], *r1 = (digit_t*)r[1];
|
||||
felm_t t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16;
|
||||
felm_t one = {0};
|
||||
one[0] = 1;
|
||||
|
||||
digit_t* x0 = (digit_t*)out->x[0];
|
||||
digit_t* x1 = (digit_t*)out->x[1];
|
||||
digit_t* y0 = (digit_t*)out->y[0];
|
||||
digit_t* y1 = (digit_t*)out->y[1];
|
||||
digit_t selector;
|
||||
|
||||
fpadd1271(r0, r1, t0);
|
||||
fpsub1271(r0, r1, t1);
|
||||
fpmul1271(t0, t1, t0);
|
||||
fpmul1271(r0, r1, t1);
|
||||
fpadd1271(t1, t1, t1);
|
||||
fpadd1271(t1, t1, t2);
|
||||
fpadd1271(t0, t2, t2);
|
||||
fpadd1271(t0, t0, t0);
|
||||
fpsub1271(t0, t1, t3);
|
||||
fpadd1271(t3, one, t0);
|
||||
fpmul1271(A0, t0, t4);
|
||||
fpmul1271(A1, t2, t1);
|
||||
fpsub1271(t1, t4, t4);
|
||||
fpmul1271(A1, t0, t5);
|
||||
fpmul1271(A0, t2, t1);
|
||||
fpadd1271(t1, t5, t1);
|
||||
fpadd1271(t0, t2, t5);
|
||||
fpsub1271(t0, t2, t6);
|
||||
fpmul1271(t5, t6, t6);
|
||||
fpmul1271(t2, t0, t5);
|
||||
fpadd1271(t5, t5, t5);
|
||||
fpmul1271(con1, t3, t7);
|
||||
fpsub1271(t6, t7, t8);
|
||||
fpmul1271(con2, t2, t7);
|
||||
fpadd1271(t7, t8, t8);
|
||||
fpmul1271(con1, t2, t7);
|
||||
fpsub1271(t5, t7, t9);
|
||||
fpmul1271(con2, t3, t7);
|
||||
fpsub1271(t9, t7, t9);
|
||||
fpmul1271(t4, t8, t5);
|
||||
fpmul1271(t1, t9, t7);
|
||||
fpadd1271(t5, t7, t7);
|
||||
fpmul1271(t4, t9, t5);
|
||||
fpmul1271(t1, t8, t10);
|
||||
fpsub1271(t5, t10, t10);
|
||||
fpsqr1271(t7, t5);
|
||||
fpsqr1271(t10, t7);
|
||||
fpadd1271(t5, t7, t5);
|
||||
fpexp1251(t5, t7);
|
||||
fpsqr1271(t7, t7);
|
||||
fpmul1271(t5, t7, t7);
|
||||
fpcopy1271(A0, t8);
|
||||
fpcopy1271(A1, t9);
|
||||
fpneg1271(t8);
|
||||
fpneg1271(t9);
|
||||
fpadd1271(A0, t4, t5);
|
||||
fpsub1271(A1, t1, t11);
|
||||
|
||||
selector = fpeq1271(t7, one);
|
||||
fpselect(t8, t5, t3, selector);
|
||||
fpselect(t9, t11, t10, selector);
|
||||
|
||||
fpmul1271(t0, t3, t5);
|
||||
fpmul1271(t2, t10, t8);
|
||||
fpsub1271(t5, t8, t8);
|
||||
fpmul1271(t2, t3, t5);
|
||||
fpmul1271(t0, t10, t9);
|
||||
fpadd1271(t5, t9, t9);
|
||||
fpadd1271(t3, t10, t5);
|
||||
fpsub1271(t3, t10, t11);
|
||||
fpmul1271(t5, t11, t5);
|
||||
fpmul1271(t3, t10, t11);
|
||||
fpadd1271(t11, t11, t11);
|
||||
fpmul1271(t3, t4, t12);
|
||||
fpmul1271(t1, t10, t13);
|
||||
fpadd1271(t12, t13, t13);
|
||||
fpmul1271(t4, t10, t14);
|
||||
fpmul1271(t1, t3, t12);
|
||||
fpsub1271(t14, t12, t12);
|
||||
fpsub1271(t5, t13, t5);
|
||||
fpsub1271(t11, t12, t11);
|
||||
fpadd1271(t5, t6, t5);
|
||||
fpmul1271(t0, t2, t6);
|
||||
fpadd1271(t6, t6, t6);
|
||||
fpadd1271(t11, t6, t11);
|
||||
fpmul1271(t5, t8, t6);
|
||||
fpmul1271(t9, t11, t12);
|
||||
fpsub1271(t6, t12, t6);
|
||||
fpmul1271(t5, t9, t12);
|
||||
fpmul1271(t8, t11, t8);
|
||||
fpadd1271(t12, t8, t12);
|
||||
fpadd1271(t6, t6, t6);
|
||||
fpadd1271(t6, t6, t6);
|
||||
fpadd1271(t6, t6, t6);
|
||||
fpadd1271(t6, t6, t6);
|
||||
fpadd1271(t12, t12, t12);
|
||||
fpadd1271(t12, t12, t12);
|
||||
fpadd1271(t12, t12, t12);
|
||||
fpadd1271(t12, t12, t12);
|
||||
fpadd1271(t0, t3, t14);
|
||||
fpadd1271(t14, t14, t14);
|
||||
fpadd1271(t2, t10, t8);
|
||||
fpadd1271(t8, t8, t8);
|
||||
fpmul1271(t6, t14, t4);
|
||||
fpmul1271(t8, t12, t1);
|
||||
fpsub1271(t4, t1, t4);
|
||||
fpmul1271(t12, t14, t9);
|
||||
fpmul1271(t6, t8, t1);
|
||||
fpadd1271(t1, t9, t1);
|
||||
fpsqr1271(t12, t5);
|
||||
fpsqr1271(t6, t9);
|
||||
fpadd1271(t5, t9, t9);
|
||||
fpsqr1271(t1, t5);
|
||||
fpsqr1271(t4, t11);
|
||||
fpadd1271(t11, t5, t11);
|
||||
fpsqr1271(t11, t5);
|
||||
fpmul1271(t5, t9, t5);
|
||||
fpexp1251(t5, t7);
|
||||
fpsqr1271(t7, t13);
|
||||
fpsqr1271(t13, t13);
|
||||
fpmul1271(t11, t13, t13);
|
||||
fpmul1271(t9, t13, t13);
|
||||
fpmul1271(t5, t13, t13);
|
||||
fpmul1271(t13, t7, t7);
|
||||
fpmul1271(t5, t7, t7);
|
||||
fpadd1271(t6, t7, t5);
|
||||
fpdiv1271(t5);
|
||||
fpexp1251(t5, t9);
|
||||
fpsqr1271(t9, t11);
|
||||
fpsqr1271(t11, t11);
|
||||
fpmul1271(t5, t11, t11);
|
||||
fpmul1271(t5, t9, t9);
|
||||
fpmul1271(t11, t12, t11);
|
||||
fpsqr1271(t9, t7);
|
||||
fpadd1271(one, one, t15);
|
||||
fpcopy1271(t11, t16);
|
||||
fpcopy1271(t15, x0);
|
||||
fpneg1271(x0);
|
||||
|
||||
selector = fpeq1271(t5, t7);
|
||||
fpselect(t15, t16, t7, selector);
|
||||
fpselect(t16, x0, t11, selector);
|
||||
|
||||
fpadd1271(t13, t13, t13);
|
||||
fpsub1271(t3, t0, y0);
|
||||
fpsub1271(t10, t2, y1);
|
||||
fpmul1271(y0, t6, t16);
|
||||
fpmul1271(y1, t12, t15);
|
||||
fpsub1271(t16, t15, t15);
|
||||
fpmul1271(y0, t12, y0);
|
||||
fpmul1271(t6, y1, t16);
|
||||
fpadd1271(t16, y0, t16);
|
||||
fpmul1271(t15, t4, x0);
|
||||
fpmul1271(t1, t16, y0);
|
||||
fpadd1271(x0, y0, y0);
|
||||
fpmul1271(t4, t16, y1);
|
||||
fpmul1271(t1, t15, x0);
|
||||
fpsub1271(y1, x0, y1);
|
||||
fpmul1271(y0, t13, y0);
|
||||
fpmul1271(y1, t13, y1);
|
||||
fpmul1271(b0, t3, t15);
|
||||
fpmul1271(b1, t10, x0);
|
||||
fpsub1271(t15, x0, t15);
|
||||
fpmul1271(b0, t10, t16);
|
||||
fpmul1271(b1, t3, x0);
|
||||
fpadd1271(t16, x0, t16);
|
||||
fpmul1271(t15, t4, t5);
|
||||
fpmul1271(t1, t16, x0);
|
||||
fpadd1271(x0, t5, x0);
|
||||
fpmul1271(t4, t16, x1);
|
||||
fpmul1271(t1, t15, t5);
|
||||
fpsub1271(x1, t5, x1);
|
||||
fpmul1271(x0, t0, t5);
|
||||
fpmul1271(x1, t2, t15);
|
||||
fpsub1271(t5, t15, t15);
|
||||
fpmul1271(x1, t0, t5);
|
||||
fpmul1271(x0, t2, t16);
|
||||
fpadd1271(t5, t16, t16);
|
||||
fpmul1271(t15, t14, t5);
|
||||
fpmul1271(t16, t8, x0);
|
||||
fpsub1271(t5, x0, x0);
|
||||
fpmul1271(t15, t8, t5);
|
||||
fpmul1271(t16, t14, x1);
|
||||
fpadd1271(x1, t5, x1);
|
||||
fpmul1271(x0, t7, t5);
|
||||
fpmul1271(x1, t11, t15);
|
||||
fpsub1271(t5, t15, t15);
|
||||
fpmul1271(t7, x1, t5);
|
||||
fpmul1271(t11, x0, t16);
|
||||
fpadd1271(t16, t5, t16);
|
||||
fpmul1271(t13, t9, t13);
|
||||
fpmul1271(t15, t13, x0);
|
||||
fpmul1271(t16, t13, x1);
|
||||
|
||||
// Clear cofactor
|
||||
point_extproj_t P;
|
||||
point_setup(out, P);
|
||||
cofactor_clearing(P);
|
||||
eccnorm(P, out);
|
||||
|
||||
return ECCRYPTO_SUCCESS;
|
||||
}
|
|
@ -107,7 +107,7 @@ else
|
|||
ASM_OBJECTS=fp2_1271.o
|
||||
endif
|
||||
endif
|
||||
OBJECTS=eccp2.o eccp2_no_endo.o eccp2_core.o $(ASM_OBJECTS) crypto_util.o schnorrq.o kex.o sha512.o random.o
|
||||
OBJECTS=eccp2.o eccp2_no_endo.o eccp2_core.o $(ASM_OBJECTS) crypto_util.o schnorrq.o hash_to_curve.o kex.o sha512.o random.o
|
||||
OBJECTS_FP_TEST=fp_tests.o $(OBJECTS) test_extras.o
|
||||
OBJECTS_ECC_TEST=ecc_tests.o $(OBJECTS) test_extras.o
|
||||
OBJECTS_CRYPTO_TEST=crypto_tests.o $(OBJECTS) test_extras.o
|
||||
|
@ -154,6 +154,9 @@ endif
|
|||
schnorrq.o: schnorrq.c
|
||||
$(CC) $(CFLAGS) schnorrq.c
|
||||
|
||||
hash_to_curve.o: hash_to_curve.c
|
||||
$(CC) $(CFLAGS) hash_to_curve.c
|
||||
|
||||
kex.o: kex.c
|
||||
$(CC) $(CFLAGS) kex.c
|
||||
|
||||
|
@ -181,5 +184,5 @@ fp_tests.o: tests/fp_tests.c
|
|||
.PHONY: clean
|
||||
|
||||
clean:
|
||||
rm -f $(SHARED_LIB_TARGET) crypto_test ecc_test fp_test fp2_1271.o fp2_1271_AVX2.o AMD64/consts.s consts.o $(OBJECTS_ALL)
|
||||
rm -rf $(SHARED_LIB_TARGET) crypto_test ecc_test fp_test *.o AMD64/consts.s
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
#include "../FourQ_api.h"
|
||||
#include "../FourQ_params.h"
|
||||
#include "../../random/random.h"
|
||||
#include "../../sha512/sha512.h"
|
||||
#include "test_extras.h"
|
||||
#include <stdio.h>
|
||||
|
||||
|
@ -139,198 +141,273 @@ ECCRYPTO_STATUS SchnorrQ_run()
|
|||
|
||||
ECCRYPTO_STATUS compressedkex_test()
|
||||
{ // Test ECDH key exchange based on FourQ
|
||||
int n, passed;
|
||||
unsigned int i;
|
||||
unsigned char SecretKeyA[32], PublicKeyA[32], SecretAgreementA[32];
|
||||
unsigned char SecretKeyB[32], PublicKeyB[32], SecretAgreementB[32];
|
||||
ECCRYPTO_STATUS Status = ECCRYPTO_SUCCESS;
|
||||
int n, passed;
|
||||
unsigned int i;
|
||||
unsigned char SecretKeyA[32], PublicKeyA[32], SecretAgreementA[32];
|
||||
unsigned char SecretKeyB[32], PublicKeyB[32], SecretAgreementB[32];
|
||||
ECCRYPTO_STATUS Status = ECCRYPTO_SUCCESS;
|
||||
|
||||
printf("\n--------------------------------------------------------------------------------------------------------\n\n");
|
||||
printf("Testing DH key exchange using compressed, 32-byte public keys: \n\n");
|
||||
printf("\n--------------------------------------------------------------------------------------------------------\n\n");
|
||||
printf("Testing DH key exchange using compressed, 32-byte public keys: \n\n");
|
||||
|
||||
passed = 1;
|
||||
for (n = 0; n < TEST_LOOPS; n++)
|
||||
{
|
||||
// Alice's keypair generation
|
||||
Status = CompressedKeyGeneration(SecretKeyA, PublicKeyA);
|
||||
if (Status != ECCRYPTO_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
// Bob's keypair generation
|
||||
Status = CompressedKeyGeneration(SecretKeyB, PublicKeyB);
|
||||
if (Status != ECCRYPTO_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
passed = 1;
|
||||
for (n = 0; n < TEST_LOOPS; n++)
|
||||
{
|
||||
// Alice's keypair generation
|
||||
Status = CompressedKeyGeneration(SecretKeyA, PublicKeyA);
|
||||
if (Status != ECCRYPTO_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
// Bob's keypair generation
|
||||
Status = CompressedKeyGeneration(SecretKeyB, PublicKeyB);
|
||||
if (Status != ECCRYPTO_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
// Alice's shared secret computation
|
||||
Status = CompressedSecretAgreement(SecretKeyA, PublicKeyB, SecretAgreementA);
|
||||
if (Status != ECCRYPTO_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
// Bob's shared secret computation
|
||||
Status = CompressedSecretAgreement(SecretKeyB, PublicKeyA, SecretAgreementB);
|
||||
if (Status != ECCRYPTO_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
// Alice's shared secret computation
|
||||
Status = CompressedSecretAgreement(SecretKeyA, PublicKeyB, SecretAgreementA);
|
||||
if (Status != ECCRYPTO_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
// Bob's shared secret computation
|
||||
Status = CompressedSecretAgreement(SecretKeyB, PublicKeyA, SecretAgreementB);
|
||||
if (Status != ECCRYPTO_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
if (SecretAgreementA[i] != SecretAgreementB[i]) {
|
||||
passed = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (passed==1) printf(" DH key exchange tests............................................................ PASSED");
|
||||
else { printf(" DH key exchange tests... FAILED"); printf("\n"); Status = ECCRYPTO_ERROR_SHARED_KEY; }
|
||||
printf("\n");
|
||||
for (i = 0; i < 32; i++) {
|
||||
if (SecretAgreementA[i] != SecretAgreementB[i]) {
|
||||
passed = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (passed==1) printf(" DH key exchange tests............................................................ PASSED");
|
||||
else { printf(" DH key exchange tests... FAILED"); printf("\n"); Status = ECCRYPTO_ERROR_SHARED_KEY; }
|
||||
printf("\n");
|
||||
|
||||
return Status;
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
ECCRYPTO_STATUS compressedkex_run()
|
||||
{ // Benchmark ECDH key exchange based on FourQ
|
||||
int n;
|
||||
unsigned long long cycles, cycles1, cycles2;
|
||||
unsigned char SecretKeyA[32], PublicKeyA[32], SecretAgreementA[32];
|
||||
unsigned char SecretKeyB[32], PublicKeyB[32];
|
||||
ECCRYPTO_STATUS Status = ECCRYPTO_SUCCESS;
|
||||
int n;
|
||||
unsigned long long cycles, cycles1, cycles2;
|
||||
unsigned char SecretKeyA[32], PublicKeyA[32], SecretAgreementA[32];
|
||||
unsigned char SecretKeyB[32], PublicKeyB[32];
|
||||
ECCRYPTO_STATUS Status = ECCRYPTO_SUCCESS;
|
||||
|
||||
printf("\n--------------------------------------------------------------------------------------------------------\n\n");
|
||||
printf("Benchmarking DH key exchange using compressed, 32-byte public keys: \n\n");
|
||||
printf("\n--------------------------------------------------------------------------------------------------------\n\n");
|
||||
printf("Benchmarking DH key exchange using compressed, 32-byte public keys: \n\n");
|
||||
|
||||
cycles = 0;
|
||||
for (n = 0; n < BENCH_LOOPS; n++)
|
||||
{
|
||||
cycles1 = cpucycles();
|
||||
Status = CompressedKeyGeneration(SecretKeyA, PublicKeyA);
|
||||
if (Status != ECCRYPTO_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
cycles2 = cpucycles();
|
||||
cycles = cycles + (cycles2 - cycles1);
|
||||
}
|
||||
printf(" Keypair generation runs in ...................................................... %8lld ", cycles/BENCH_LOOPS); print_unit;
|
||||
printf("\n");
|
||||
|
||||
Status = CompressedKeyGeneration(SecretKeyB, PublicKeyB);
|
||||
cycles = 0;
|
||||
for (n = 0; n < BENCH_LOOPS; n++)
|
||||
{
|
||||
cycles1 = cpucycles();
|
||||
Status = CompressedSecretAgreement(SecretKeyA, PublicKeyB, SecretAgreementA);
|
||||
if (Status != ECCRYPTO_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
cycles2 = cpucycles();
|
||||
cycles = cycles + (cycles2 - cycles1);
|
||||
}
|
||||
printf(" Secret agreement runs in ........................................................ %8lld ", cycles/BENCH_LOOPS); print_unit;
|
||||
printf("\n");
|
||||
cycles = 0;
|
||||
for (n = 0; n < BENCH_LOOPS; n++)
|
||||
{
|
||||
cycles1 = cpucycles();
|
||||
Status = CompressedKeyGeneration(SecretKeyA, PublicKeyA);
|
||||
if (Status != ECCRYPTO_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
cycles2 = cpucycles();
|
||||
cycles = cycles + (cycles2 - cycles1);
|
||||
}
|
||||
printf(" Keypair generation runs in ...................................................... %8lld ", cycles/BENCH_LOOPS); print_unit;
|
||||
printf("\n");
|
||||
|
||||
Status = CompressedKeyGeneration(SecretKeyB, PublicKeyB);
|
||||
cycles = 0;
|
||||
for (n = 0; n < BENCH_LOOPS; n++)
|
||||
{
|
||||
cycles1 = cpucycles();
|
||||
Status = CompressedSecretAgreement(SecretKeyA, PublicKeyB, SecretAgreementA);
|
||||
if (Status != ECCRYPTO_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
cycles2 = cpucycles();
|
||||
cycles = cycles + (cycles2 - cycles1);
|
||||
}
|
||||
printf(" Secret agreement runs in ........................................................ %8lld ", cycles/BENCH_LOOPS); print_unit;
|
||||
printf("\n");
|
||||
|
||||
return Status;
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
ECCRYPTO_STATUS kex_test()
|
||||
{ // Test ECDH key exchange based on FourQ
|
||||
int n, passed;
|
||||
unsigned int i;
|
||||
unsigned char SecretKeyA[32], PublicKeyA[64], SecretAgreementA[32];
|
||||
unsigned char SecretKeyB[32], PublicKeyB[64], SecretAgreementB[32];
|
||||
ECCRYPTO_STATUS Status = ECCRYPTO_SUCCESS;
|
||||
int n, passed;
|
||||
unsigned int i;
|
||||
unsigned char SecretKeyA[32], PublicKeyA[64], SecretAgreementA[32];
|
||||
unsigned char SecretKeyB[32], PublicKeyB[64], SecretAgreementB[32];
|
||||
ECCRYPTO_STATUS Status = ECCRYPTO_SUCCESS;
|
||||
|
||||
printf("\n--------------------------------------------------------------------------------------------------------\n\n");
|
||||
printf("Testing DH key exchange using uncompressed, 64-byte public keys: \n\n");
|
||||
printf("\n--------------------------------------------------------------------------------------------------------\n\n");
|
||||
printf("Testing DH key exchange using uncompressed, 64-byte public keys: \n\n");
|
||||
|
||||
passed = 1;
|
||||
for (n = 0; n < TEST_LOOPS; n++)
|
||||
{
|
||||
// Alice's keypair generation
|
||||
Status = KeyGeneration(SecretKeyA, PublicKeyA);
|
||||
if (Status != ECCRYPTO_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
// Bob's keypair generation
|
||||
Status = KeyGeneration(SecretKeyB, PublicKeyB);
|
||||
if (Status != ECCRYPTO_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
passed = 1;
|
||||
for (n = 0; n < TEST_LOOPS; n++)
|
||||
{
|
||||
// Alice's keypair generation
|
||||
Status = KeyGeneration(SecretKeyA, PublicKeyA);
|
||||
if (Status != ECCRYPTO_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
// Bob's keypair generation
|
||||
Status = KeyGeneration(SecretKeyB, PublicKeyB);
|
||||
if (Status != ECCRYPTO_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
// Alice's shared secret computation
|
||||
Status = SecretAgreement(SecretKeyA, PublicKeyB, SecretAgreementA);
|
||||
if (Status != ECCRYPTO_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
// Bob's shared secret computation
|
||||
Status = SecretAgreement(SecretKeyB, PublicKeyA, SecretAgreementB);
|
||||
if (Status != ECCRYPTO_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
// Alice's shared secret computation
|
||||
Status = SecretAgreement(SecretKeyA, PublicKeyB, SecretAgreementA);
|
||||
if (Status != ECCRYPTO_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
// Bob's shared secret computation
|
||||
Status = SecretAgreement(SecretKeyB, PublicKeyA, SecretAgreementB);
|
||||
if (Status != ECCRYPTO_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
if (SecretAgreementA[i] != SecretAgreementB[i]) {
|
||||
passed = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (passed==1) printf(" DH key exchange tests............................................................ PASSED");
|
||||
else { printf(" DH key exchange tests... FAILED"); printf("\n"); Status = ECCRYPTO_ERROR_SHARED_KEY; }
|
||||
printf("\n");
|
||||
for (i = 0; i < 32; i++) {
|
||||
if (SecretAgreementA[i] != SecretAgreementB[i]) {
|
||||
passed = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (passed==1) printf(" DH key exchange tests............................................................ PASSED");
|
||||
else { printf(" DH key exchange tests... FAILED"); printf("\n"); Status = ECCRYPTO_ERROR_SHARED_KEY; }
|
||||
printf("\n");
|
||||
|
||||
return Status;
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
ECCRYPTO_STATUS kex_run()
|
||||
{ // Benchmark ECDH key exchange based on FourQ
|
||||
int n;
|
||||
unsigned long long cycles, cycles1, cycles2;
|
||||
unsigned char SecretKeyA[32], PublicKeyA[64], SecretAgreementA[32];
|
||||
unsigned char SecretKeyB[32], PublicKeyB[64];
|
||||
ECCRYPTO_STATUS Status = ECCRYPTO_SUCCESS;
|
||||
int n;
|
||||
unsigned long long cycles, cycles1, cycles2;
|
||||
unsigned char SecretKeyA[32], PublicKeyA[64], SecretAgreementA[32];
|
||||
unsigned char SecretKeyB[32], PublicKeyB[64];
|
||||
ECCRYPTO_STATUS Status = ECCRYPTO_SUCCESS;
|
||||
|
||||
printf("\n--------------------------------------------------------------------------------------------------------\n\n");
|
||||
printf("Benchmarking DH key exchange using uncompressed, 64-byte public keys: \n\n");
|
||||
printf("\n--------------------------------------------------------------------------------------------------------\n\n");
|
||||
printf("Benchmarking DH key exchange using uncompressed, 64-byte public keys: \n\n");
|
||||
|
||||
cycles = 0;
|
||||
for (n = 0; n < BENCH_LOOPS; n++)
|
||||
{
|
||||
cycles1 = cpucycles();
|
||||
Status = KeyGeneration(SecretKeyA, PublicKeyA);
|
||||
if (Status != ECCRYPTO_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
cycles2 = cpucycles();
|
||||
cycles = cycles + (cycles2 - cycles1);
|
||||
}
|
||||
printf(" Keypair generation runs in ...................................................... %8lld ", cycles/BENCH_LOOPS); print_unit;
|
||||
printf("\n");
|
||||
cycles = 0;
|
||||
for (n = 0; n < BENCH_LOOPS; n++)
|
||||
{
|
||||
cycles1 = cpucycles();
|
||||
Status = KeyGeneration(SecretKeyA, PublicKeyA);
|
||||
if (Status != ECCRYPTO_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
cycles2 = cpucycles();
|
||||
cycles = cycles + (cycles2 - cycles1);
|
||||
}
|
||||
printf(" Keypair generation runs in ...................................................... %8lld ", cycles/BENCH_LOOPS); print_unit;
|
||||
printf("\n");
|
||||
|
||||
Status = KeyGeneration(SecretKeyB, PublicKeyB);
|
||||
cycles = 0;
|
||||
for (n = 0; n < BENCH_LOOPS; n++)
|
||||
{
|
||||
cycles1 = cpucycles();
|
||||
Status = SecretAgreement(SecretKeyA, PublicKeyB, SecretAgreementA);
|
||||
if (Status != ECCRYPTO_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
cycles2 = cpucycles();
|
||||
cycles = cycles + (cycles2 - cycles1);
|
||||
}
|
||||
printf(" Secret agreement runs in ........................................................ %8lld ", cycles/BENCH_LOOPS); print_unit;
|
||||
printf("\n");
|
||||
Status = KeyGeneration(SecretKeyB, PublicKeyB);
|
||||
cycles = 0;
|
||||
for (n = 0; n < BENCH_LOOPS; n++)
|
||||
{
|
||||
cycles1 = cpucycles();
|
||||
Status = SecretAgreement(SecretKeyA, PublicKeyB, SecretAgreementA);
|
||||
if (Status != ECCRYPTO_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
cycles2 = cpucycles();
|
||||
cycles = cycles + (cycles2 - cycles1);
|
||||
}
|
||||
printf(" Secret agreement runs in ........................................................ %8lld ", cycles/BENCH_LOOPS); print_unit;
|
||||
printf("\n");
|
||||
|
||||
return Status;
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
ECCRYPTO_STATUS hash2curve_test()
|
||||
{ // Test hashing to FourQ
|
||||
int n, passed;
|
||||
point_t P, Q;
|
||||
point_extproj_t R;
|
||||
unsigned char Value[32], HashedValue[64];
|
||||
f2elm_t* f2elmt = (f2elm_t*)&HashedValue[0];
|
||||
ECCRYPTO_STATUS Status = ECCRYPTO_SUCCESS;
|
||||
|
||||
printf("\n--------------------------------------------------------------------------------------------------------\n\n");
|
||||
printf("Testing hashing to FourQ: \n\n");
|
||||
|
||||
passed = 1;
|
||||
for (n = 0; n < TEST_LOOPS; n++)
|
||||
{
|
||||
RandomBytesFunction(Value, 32);
|
||||
CryptoHashFunction(Value, 32, HashedValue);
|
||||
mod1271(((felm_t*)f2elmt)[0]);
|
||||
mod1271(((felm_t*)f2elmt)[1]);
|
||||
|
||||
// Hash GF(p^2) element to curve
|
||||
Status = HashToCurve((felm_t*)f2elmt, P);
|
||||
if (Status != ECCRYPTO_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
hash2curve_unsafe((felm_t*)f2elmt, Q); // Non-constant-time version for testing
|
||||
if (fp2compare64((uint64_t*)P->x,(uint64_t*)Q->x)!=0 || fp2compare64((uint64_t*)P->y,(uint64_t*)Q->y)!=0) { passed=0; break; }
|
||||
|
||||
// Check if point is on the curve
|
||||
point_setup(P, R);
|
||||
if (!ecc_point_validate(R)) { passed=0; break; }
|
||||
}
|
||||
if (passed==1) printf(" Hash to FourQ tests.............................................................. PASSED");
|
||||
else { printf(" Hash to FourQ tests... FAILED"); printf("\n"); Status = ECCRYPTO_ERROR_HASH_TO_CURVE; }
|
||||
printf("\n");
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
ECCRYPTO_STATUS hash2curve_run()
|
||||
{ // Benchmark hashing to FourQ
|
||||
int n;
|
||||
unsigned long long cycles, cycles1, cycles2;
|
||||
point_t P;
|
||||
unsigned char Value[32], HashedValue[64];
|
||||
f2elm_t* f2elmt = (f2elm_t*)&HashedValue[0];
|
||||
ECCRYPTO_STATUS Status = ECCRYPTO_SUCCESS;
|
||||
|
||||
printf("\n--------------------------------------------------------------------------------------------------------\n\n");
|
||||
printf("Benchmarking hashing to FourQ: \n\n");
|
||||
|
||||
cycles = 0;
|
||||
for (n = 0; n < BENCH_LOOPS; n++)
|
||||
{
|
||||
RandomBytesFunction(Value, 32);
|
||||
CryptoHashFunction(Value, 32, HashedValue);
|
||||
mod1271(((felm_t*)f2elmt)[0]);
|
||||
mod1271(((felm_t*)f2elmt)[1]);
|
||||
|
||||
cycles1 = cpucycles();
|
||||
Status = HashToCurve((felm_t*)f2elmt, P);
|
||||
if (Status != ECCRYPTO_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
cycles2 = cpucycles();
|
||||
cycles = cycles + (cycles2 - cycles1);
|
||||
}
|
||||
printf(" Hashing to FourQ runs in ....................................................... %8lld ", cycles/BENCH_LOOPS); print_unit;
|
||||
printf("\n");
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
ECCRYPTO_STATUS Status = ECCRYPTO_SUCCESS;
|
||||
|
||||
|
||||
Status = SchnorrQ_test(); // Test SchnorrQ signature scheme
|
||||
if (Status != ECCRYPTO_SUCCESS) {
|
||||
printf("\n\n Error detected: %s \n\n", FourQ_get_error_message(Status));
|
||||
|
@ -342,27 +419,38 @@ int main()
|
|||
return false;
|
||||
}
|
||||
|
||||
Status = compressedkex_test(); // Test Diffie-Hellman key exchange using compressed public keys
|
||||
if (Status != ECCRYPTO_SUCCESS) {
|
||||
printf("\n\n Error detected: %s \n\n", FourQ_get_error_message(Status));
|
||||
return false;
|
||||
}
|
||||
Status = compressedkex_run(); // Benchmark Diffie-Hellman key exchange using compressed public keys
|
||||
if (Status != ECCRYPTO_SUCCESS) {
|
||||
printf("\n\n Error detected: %s \n\n", FourQ_get_error_message(Status));
|
||||
return false;
|
||||
}
|
||||
Status = compressedkex_test(); // Test Diffie-Hellman key exchange using compressed public keys
|
||||
if (Status != ECCRYPTO_SUCCESS) {
|
||||
printf("\n\n Error detected: %s \n\n", FourQ_get_error_message(Status));
|
||||
return false;
|
||||
}
|
||||
Status = compressedkex_run(); // Benchmark Diffie-Hellman key exchange using compressed public keys
|
||||
if (Status != ECCRYPTO_SUCCESS) {
|
||||
printf("\n\n Error detected: %s \n\n", FourQ_get_error_message(Status));
|
||||
return false;
|
||||
}
|
||||
|
||||
Status = kex_test(); // Test Diffie-Hellman key exchange using uncompressed public keys
|
||||
if (Status != ECCRYPTO_SUCCESS) {
|
||||
printf("\n\n Error detected: %s \n\n", FourQ_get_error_message(Status));
|
||||
return false;
|
||||
}
|
||||
Status = kex_run(); // Benchmark Diffie-Hellman key exchange using uncompressed public keys
|
||||
if (Status != ECCRYPTO_SUCCESS) {
|
||||
printf("\n\n Error detected: %s \n\n", FourQ_get_error_message(Status));
|
||||
return false;
|
||||
}
|
||||
Status = kex_test(); // Test Diffie-Hellman key exchange using uncompressed public keys
|
||||
if (Status != ECCRYPTO_SUCCESS) {
|
||||
printf("\n\n Error detected: %s \n\n", FourQ_get_error_message(Status));
|
||||
return false;
|
||||
}
|
||||
Status = kex_run(); // Benchmark Diffie-Hellman key exchange using uncompressed public keys
|
||||
if (Status != ECCRYPTO_SUCCESS) {
|
||||
printf("\n\n Error detected: %s \n\n", FourQ_get_error_message(Status));
|
||||
return false;
|
||||
}
|
||||
|
||||
Status = hash2curve_test(); // Test hash to FourQ function
|
||||
if (Status != ECCRYPTO_SUCCESS) {
|
||||
printf("\n\n Error detected: %s \n\n", FourQ_get_error_message(Status));
|
||||
return false;
|
||||
}
|
||||
Status = hash2curve_run(); // Benchmark hash to FourQ function
|
||||
if (Status != ECCRYPTO_SUCCESS) {
|
||||
printf("\n\n Error detected: %s \n\n", FourQ_get_error_message(Status));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
|
@ -70,28 +70,28 @@ void random_scalar_test(uint64_t* a)
|
|||
void fp2random1271_test(f2elm_t a)
|
||||
{ // Generating a pseudo-random GF(p^2) element a+b*i, where a,b in [0, 2^127-1]
|
||||
// NOTE: distribution is not fully uniform. TO BE USED FOR TESTING ONLY.
|
||||
digit_t mask_7fff = (digit_t)-1 >> 1;
|
||||
digit_t mask_7fff = (digit_t)-1 >> 1;
|
||||
|
||||
random_scalar_test((uint64_t*)&a[0]);
|
||||
a[0][NWORDS_FIELD - 1] &= mask_7fff;
|
||||
a[1][NWORDS_FIELD - 1] &= mask_7fff;
|
||||
random_scalar_test((uint64_t*)&a[0]);
|
||||
a[0][NWORDS_FIELD - 1] &= mask_7fff;
|
||||
a[1][NWORDS_FIELD - 1] &= mask_7fff;
|
||||
}
|
||||
|
||||
|
||||
void random_order_test(digit_t* a)
|
||||
{ // Generating a pseudo-random element in [0, order-1]
|
||||
// SECURITY NOTE: distribution is not fully uniform. TO BE USED FOR TESTING ONLY.
|
||||
int i;
|
||||
unsigned char* string = (unsigned char*)a;
|
||||
int i;
|
||||
unsigned char* string = (unsigned char*)a;
|
||||
|
||||
for (i = 0; i < 31; i++) {
|
||||
string[i] = (unsigned char)rand(); // Obtain 246-bit number
|
||||
}
|
||||
string[30] &= 0x3F;
|
||||
string[31] = 0;
|
||||
subtract_mod_order(a, (digit_t*)&curve_order, a);
|
||||
for (i = 0; i < 31; i++) {
|
||||
string[i] = (unsigned char)rand(); // Obtain 246-bit number
|
||||
}
|
||||
string[30] &= 0x3F;
|
||||
string[31] = 0;
|
||||
subtract_mod_order(a, (digit_t*)&curve_order, a);
|
||||
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
@ -169,3 +169,221 @@ bool verify_mLSB_recoding(uint64_t* scalar, int* digits)
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static inline bool fpeq1271_unsafe(felm_t in1, felm_t in2)
|
||||
{
|
||||
return memcmp(in1, in2, sizeof(felm_t)) == 0;
|
||||
}
|
||||
|
||||
|
||||
void hash2curve_unsafe(f2elm_t r, point_t out)
|
||||
{ // (Unsafe, non-constant-time version of) hash to curve function for testing
|
||||
digit_t *r0 = (digit_t*)r[0], *r1 = (digit_t*)r[1];
|
||||
felm_t t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18;
|
||||
felm_t one = {0};
|
||||
one[0] = 1;
|
||||
|
||||
digit_t* x0 = (digit_t*)out->x[0];
|
||||
digit_t* x1 = (digit_t*)out->x[1];
|
||||
digit_t* y0 = (digit_t*)out->y[0];
|
||||
digit_t* y1 = (digit_t*)out->y[1];
|
||||
|
||||
fpadd1271(r0, r1, t0);
|
||||
fpsub1271(r0, r1, t1);
|
||||
fpmul1271(t0, t1, t0);
|
||||
fpmul1271(r0, r1, t1);
|
||||
fpadd1271(t1, t1, t1);
|
||||
fpadd1271(t1, t1, t2);
|
||||
fpadd1271(t0, t2, t2);
|
||||
fpadd1271(t0, t0, t0);
|
||||
fpsub1271(t0, t1, t3);
|
||||
fpadd1271(t3, one, t0);
|
||||
fpmul1271(A0, t0, t4);
|
||||
fpmul1271(A1, t2, t1);
|
||||
fpsub1271(t1, t4, t4);
|
||||
fpmul1271(A1, t0, t5);
|
||||
fpmul1271(A0, t2, t1);
|
||||
fpadd1271(t1, t5, t1);
|
||||
fpadd1271(t0, t2, t5);
|
||||
fpsub1271(t0, t2, t6);
|
||||
fpmul1271(t5, t6, t6);
|
||||
fpmul1271(t2, t0, t5);
|
||||
fpadd1271(t5, t5, t5);
|
||||
fpmul1271(con1, t3, t7);
|
||||
fpsub1271(t6, t7, t8);
|
||||
fpmul1271(con2, t2, t7);
|
||||
fpadd1271(t7, t8, t8);
|
||||
fpmul1271(con1, t2, t7);
|
||||
fpsub1271(t5, t7, t9);
|
||||
fpmul1271(con2, t3, t7);
|
||||
fpsub1271(t9, t7, t9);
|
||||
fpmul1271(t4, t8, t5);
|
||||
fpmul1271(t1, t9, t7);
|
||||
fpadd1271(t5, t7, t7);
|
||||
fpmul1271(t4, t9, t5);
|
||||
fpmul1271(t1, t8, t10);
|
||||
fpsub1271(t5, t10, t10);
|
||||
fpsqr1271(t7, t5);
|
||||
fpsqr1271(t10, t7);
|
||||
fpadd1271(t5, t7, t5);
|
||||
fpexp1251(t5, t7);
|
||||
fpsqr1271(t7, t7);
|
||||
fpmul1271(t5, t7, t7);
|
||||
fpcopy1271(A0, t8);
|
||||
fpcopy1271(A1, t9);
|
||||
fpneg1271(t8);
|
||||
fpneg1271(t9);
|
||||
fpadd1271(A0, t4, t5);
|
||||
fpsub1271(A1, t1, t11);
|
||||
|
||||
if (fpeq1271_unsafe(t7, one)) {
|
||||
fpcopy1271(t8, t3);
|
||||
fpcopy1271(t9, t10);
|
||||
} else {
|
||||
fpcopy1271(t5, t3);
|
||||
fpcopy1271(t11, t10);
|
||||
}
|
||||
|
||||
fpmul1271(t0, t3, t5);
|
||||
fpmul1271(t2, t10, t8);
|
||||
fpsub1271(t5, t8, t8);
|
||||
fpmul1271(t2, t3, t5);
|
||||
fpmul1271(t0, t10, t9);
|
||||
fpadd1271(t5, t9, t9);
|
||||
fpadd1271(t3, t10, t5);
|
||||
fpsub1271(t3, t10, t11);
|
||||
fpmul1271(t5, t11, t5);
|
||||
fpmul1271(t3, t10, t11);
|
||||
fpadd1271(t11, t11, t11);
|
||||
fpmul1271(t3, t4, t12);
|
||||
fpmul1271(t1, t10, t13);
|
||||
fpadd1271(t12, t13, t13);
|
||||
fpmul1271(t4, t10, t14);
|
||||
fpmul1271(t1, t3, t12);
|
||||
fpsub1271(t14, t12, t12);
|
||||
fpsub1271(t5, t13, t5);
|
||||
fpsub1271(t11, t12, t11);
|
||||
fpadd1271(t5, t6, t5);
|
||||
fpmul1271(t0, t2, t6);
|
||||
fpadd1271(t6, t6, t6);
|
||||
fpadd1271(t11, t6, t11);
|
||||
fpmul1271(t5, t8, t6);
|
||||
fpmul1271(t9, t11, t12);
|
||||
fpsub1271(t6, t12, t6);
|
||||
fpmul1271(t5, t9, t12);
|
||||
fpmul1271(t8, t11, t8);
|
||||
fpadd1271(t12, t8, t12);
|
||||
fpadd1271(t6, t6, t6);
|
||||
fpadd1271(t6, t6, t6);
|
||||
fpadd1271(t6, t6, t6);
|
||||
fpadd1271(t6, t6, t6);
|
||||
fpadd1271(t12, t12, t12);
|
||||
fpadd1271(t12, t12, t12);
|
||||
fpadd1271(t12, t12, t12);
|
||||
fpadd1271(t12, t12, t12);
|
||||
fpadd1271(t0, t3, t14);
|
||||
fpadd1271(t14, t14, t14);
|
||||
fpadd1271(t2, t10, t8);
|
||||
fpadd1271(t8, t8, t8);
|
||||
fpmul1271(t6, t14, t4);
|
||||
fpmul1271(t8, t12, t1);
|
||||
fpsub1271(t4, t1, t4);
|
||||
fpmul1271(t12, t14, t9);
|
||||
fpmul1271(t6, t8, t1);
|
||||
fpadd1271(t1, t9, t1);
|
||||
fpsqr1271(t12, t5);
|
||||
fpsqr1271(t6, t9);
|
||||
fpadd1271(t5, t9, t9);
|
||||
fpsqr1271(t1, t5);
|
||||
fpsqr1271(t4, t11);
|
||||
fpadd1271(t11, t5, t11);
|
||||
fpsqr1271(t11, t5);
|
||||
fpmul1271(t5, t9, t5);
|
||||
fpexp1251(t5, t7);
|
||||
fpsqr1271(t7, t13);
|
||||
fpsqr1271(t13, t13);
|
||||
fpmul1271(t11, t13, t13);
|
||||
fpmul1271(t9, t13, t13);
|
||||
fpmul1271(t5, t13, t13);
|
||||
fpmul1271(t13, t7, t7);
|
||||
fpmul1271(t5, t7, t7);
|
||||
fpadd1271(t6, t7, t5);
|
||||
fpdiv1271(t5);
|
||||
fpexp1251(t5, t9);
|
||||
fpsqr1271(t9, t11);
|
||||
fpsqr1271(t11, t11);
|
||||
fpmul1271(t5, t11, t11);
|
||||
fpmul1271(t5, t9, t9);
|
||||
fpmul1271(t11, t12, t11);
|
||||
fpsqr1271(t9, t7);
|
||||
fpadd1271(one, one, t15);
|
||||
fpcopy1271(t11, t16);
|
||||
fpcopy1271(t15, x0);
|
||||
fpneg1271(x0);
|
||||
|
||||
if (fpeq1271_unsafe(t5, t7)) {
|
||||
fpcopy1271(t15, t17);
|
||||
fpcopy1271(t16, t18);
|
||||
} else {
|
||||
fpcopy1271(t16, t17);
|
||||
fpcopy1271(x0, t18);
|
||||
}
|
||||
|
||||
fpadd1271(t13, t13, t13);
|
||||
fpsub1271(t3, t0, y0);
|
||||
fpsub1271(t10, t2, y1);
|
||||
fpmul1271(y0, t6, t16);
|
||||
fpmul1271(y1, t12, t15);
|
||||
fpsub1271(t16, t15, t15);
|
||||
fpmul1271(y0, t12, y0);
|
||||
fpmul1271(t6, y1, t16);
|
||||
fpadd1271(t16, y0, t16);
|
||||
fpmul1271(t15, t4, x0);
|
||||
fpmul1271(t1, t16, y0);
|
||||
fpadd1271(x0, y0, y0);
|
||||
fpmul1271(t4, t16, y1);
|
||||
fpmul1271(t1, t15, x0);
|
||||
fpsub1271(y1, x0, y1);
|
||||
fpmul1271(y0, t13, y0);
|
||||
fpmul1271(y1, t13, y1);
|
||||
fpmul1271(b0, t3, t15);
|
||||
fpmul1271(b1, t10, x0);
|
||||
fpsub1271(t15, x0, t15);
|
||||
fpmul1271(b0, t10, t16);
|
||||
fpmul1271(b1, t3, x0);
|
||||
fpadd1271(t16, x0, t16);
|
||||
fpmul1271(t15, t4, t5);
|
||||
fpmul1271(t1, t16, x0);
|
||||
fpadd1271(x0, t5, x0);
|
||||
fpmul1271(t4, t16, x1);
|
||||
fpmul1271(t1, t15, t5);
|
||||
fpsub1271(x1, t5, x1);
|
||||
fpmul1271(x0, t0, t5);
|
||||
fpmul1271(x1, t2, t15);
|
||||
fpsub1271(t5, t15, t15);
|
||||
fpmul1271(x1, t0, t5);
|
||||
fpmul1271(x0, t2, t16);
|
||||
fpadd1271(t5, t16, t16);
|
||||
fpmul1271(t15, t14, t5);
|
||||
fpmul1271(t16, t8, x0);
|
||||
fpsub1271(t5, x0, x0);
|
||||
fpmul1271(t15, t8, t5);
|
||||
fpmul1271(t16, t14, x1);
|
||||
fpadd1271(x1, t5, x1);
|
||||
fpmul1271(x0, t17, t5);
|
||||
fpmul1271(x1, t18, t15);
|
||||
fpsub1271(t5, t15, t15);
|
||||
fpmul1271(t17, x1, t5);
|
||||
fpmul1271(t18, x0, t16);
|
||||
fpadd1271(t16, t5, t16);
|
||||
fpmul1271(t13, t9, t13);
|
||||
fpmul1271(t15, t13, x0);
|
||||
fpmul1271(t16, t13, x1);
|
||||
|
||||
// Clear cofactor
|
||||
point_extproj_t P;
|
||||
point_setup(out, P);
|
||||
cofactor_clearing(P);
|
||||
eccnorm(P, out);
|
||||
}
|
||||
|
|
|
@ -41,6 +41,9 @@ void random_order_test(digit_t* a);
|
|||
// Verification of the mLSB-set's recoding algorithm used in fixed-base scalar multiplication
|
||||
bool verify_mLSB_recoding(uint64_t* scalar, int* digits);
|
||||
|
||||
// (Unsafe, non-constant-time version of) hash to curve function for testing
|
||||
void hash2curve_unsafe(f2elm_t r, point_t out);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
16
README.md
16
README.md
|
@ -1,4 +1,4 @@
|
|||
## FourQlib v3.0 (C Edition)
|
||||
## FourQlib v3.1 (C Edition)
|
||||
|
||||
**FourQlib** implements essential elliptic curve and cryptographic functions based on FourQ,
|
||||
a high-security, high-performance elliptic curve that targets the 128-bit security level [1]. At the
|
||||
|
@ -10,7 +10,7 @@ The library was developed by [Microsoft Research](http://research.microsoft.com/
|
|||
|
||||
## Contents
|
||||
|
||||
Version 3.0 includes the following implementations:
|
||||
Version 3.1 includes the following implementations:
|
||||
|
||||
* [`FourQ_32bit`](FourQ_32bit/): a portable implementation especially tailored for 32-bit platforms.
|
||||
* [`FourQ_64bit_and_portable`](FourQ_64bit_and_portable/): a portable implementation for 32-bit and 64-bit platforms with optional
|
||||
|
@ -34,17 +34,23 @@ The library includes an implementation of SHA-512 which is used by default by Sc
|
|||
Users can provide their own PRNG and hash implementations by replacing the functions in the [`random`](random/) and [`sha512`](sha512/)folders, and applying the corresponding changes to the settings in `FourQ.h` (in a given implementation).
|
||||
Refer to [2] for the security requirements for the cryptographic hash function.
|
||||
|
||||
## What's new in version 3.0
|
||||
## What's new
|
||||
|
||||
### In version 3.0
|
||||
|
||||
* New support for co-factor ECDH and SchnorrQ signatures.
|
||||
* New implementations for 32-bit processors, 32-bit ARMv6 and ARMv7 processors, and 32-bit ARM Cortex-M4 microcontroller.
|
||||
* New implementation for ARMv6/ARMv7/ARMv7-M with strong countermeasures against several side-channel attacks.
|
||||
* New support for 64-bit ARMv8 processors.
|
||||
|
||||
### In version 3.1
|
||||
|
||||
* New hash to curve functionality (only supported in the portable implementation FourQ_64bit_and_portable).
|
||||
|
||||
## Main features
|
||||
|
||||
* Support for co-factor Elliptic Curve Diffie-Hellman (ECDH) key exchange [3].
|
||||
* Support for the SchnorrQ digital signature scheme [2].
|
||||
* Support for co-factor Elliptic Curve Diffie-Hellman (ECDH) key exchange [3], the SchnorrQ digital signature scheme [2], and
|
||||
hash to curve conversion.
|
||||
* Support for 3 core elliptic curve operations: variable-base, fixed-base and double-scalar multiplications.
|
||||
* Support for Windows using Microsoft Visual Studio and Linux using GNU GCC or clang.
|
||||
* Includes a basic implementation using portable C to enable support on a wide range of platforms including x64, x86
|
||||
|
|
Загрузка…
Ссылка в новой задаче