192 lines
5.2 KiB
C++
192 lines
5.2 KiB
C++
|
/*
|
||
|
* Copyright (c) 2012-2020 MIRACL UK Ltd.
|
||
|
*
|
||
|
* This file is part of MIRACL Core
|
||
|
* (see https://github.com/miracl/core).
|
||
|
*
|
||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
* you may not use this file except in compliance with the License.
|
||
|
* You may obtain a copy of the License at
|
||
|
*
|
||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||
|
*
|
||
|
* Unless required by applicable law or agreed to in writing, software
|
||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
* See the License for the specific language governing permissions and
|
||
|
* limitations under the License.
|
||
|
*/
|
||
|
|
||
|
/* test driver and function exerciser for EDDSA API Functions */
|
||
|
|
||
|
// Test Vectors from RFC8032
|
||
|
|
||
|
// Observe that NIST standard does not support Ed25519ctx
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
#include <time.h>
|
||
|
#include "randapi.h"
|
||
|
#include "eddsa_Ed25519.h"
|
||
|
#include "eddsa_Ed448.h"
|
||
|
|
||
|
|
||
|
using namespace core;
|
||
|
|
||
|
// prehash message
|
||
|
static void PH_Ed25519(octet *M,octet *HM) {
|
||
|
hash512 sh512;
|
||
|
HASH512_init(&sh512);
|
||
|
for (int i=0;i<M->len;i++ )
|
||
|
HASH512_process(&sh512,M->val[i]);
|
||
|
HASH512_hash(&sh512,HM->val);
|
||
|
HM->len=64;
|
||
|
}
|
||
|
|
||
|
static void PH_Ed448(octet *M,octet *HM) {
|
||
|
sha3 SHA3;
|
||
|
SHA3_init(&SHA3,SHAKE256);
|
||
|
for (int i=0;i<M->len;i++)
|
||
|
SHA3_process(&SHA3,M->val[i]);
|
||
|
SHA3_shake(&SHA3,HM->val,64);
|
||
|
HM->len=64;
|
||
|
}
|
||
|
|
||
|
int eddsa_Ed25519(csprng *RNG)
|
||
|
{
|
||
|
using namespace Ed25519;
|
||
|
|
||
|
char d[EGS_Ed25519], q[EFS_Ed25519], m[256], sig[2*EFS_Ed25519], hm[64];
|
||
|
octet D = {0, sizeof(d), d};
|
||
|
octet Q = {0, sizeof(q), q};
|
||
|
octet M = {0, sizeof(m), m};
|
||
|
octet SIG = {0, sizeof(sig), sig};
|
||
|
octet HM={0,sizeof(hm),hm};
|
||
|
bool prehash=false;
|
||
|
bool verify;
|
||
|
|
||
|
// 32 bytes
|
||
|
// OCT_fromHex(&D,(char *)"9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60");
|
||
|
OCT_fromHex(&D,(char *)"c5aa8df43f9f837bedb7442f31dcb7b166d38535076f094b85ce3a2e0b4458f7");
|
||
|
// OCT_fromHex(&D,(char *)"833fe62409237b9d62ec77587520911e9a759cec1d19755b7da901b96dca3d42");
|
||
|
|
||
|
EDDSA_KEY_PAIR_GENERATE(NULL, &D, &Q);
|
||
|
printf("Secret key= 0x");
|
||
|
OCT_output(&D);
|
||
|
printf("Public key= 0x");
|
||
|
OCT_output(&Q);
|
||
|
printf("\n");
|
||
|
|
||
|
M.len=2; M.val[0]=0xaf; M.val[1]=0x82;
|
||
|
// M.len=3; M.val[0]=0x61; M.val[1]=0x62; M.val[2]=0x63;
|
||
|
|
||
|
if (prehash) {
|
||
|
PH_Ed25519(&M,&HM);
|
||
|
EDDSA_SIGNATURE(true,&D, NULL,&HM, &SIG);
|
||
|
} else {
|
||
|
EDDSA_SIGNATURE(false,&D, NULL,&M, &SIG);
|
||
|
}
|
||
|
printf("Signature= 0x");
|
||
|
OCT_output(&SIG);
|
||
|
|
||
|
|
||
|
if (prehash) {
|
||
|
PH_Ed25519(&M,&HM);
|
||
|
verify=EDDSA_VERIFY(true,&Q, NULL ,&HM, &SIG);
|
||
|
} else {
|
||
|
verify=EDDSA_VERIFY(false,&Q, NULL ,&M, &SIG);
|
||
|
}
|
||
|
if (verify)
|
||
|
printf("Signature is verified\n");
|
||
|
else
|
||
|
printf("Signature is NOT verified\n");
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
int eddsa_Ed448(csprng *RNG)
|
||
|
{
|
||
|
using namespace Ed448;
|
||
|
|
||
|
char d[EGS_Ed448+1], q[EFS_Ed448 + 1], m[256], sig[2*EFS_Ed448+2], ctx[256], hm[64];
|
||
|
octet D = {0, sizeof(d), d};
|
||
|
octet Q = {0, sizeof(q), q};
|
||
|
octet M = {0, sizeof(m), m};
|
||
|
octet SIG = {0, sizeof(sig), sig};
|
||
|
octet CTX = {0, sizeof(ctx), ctx};
|
||
|
octet HM={0,sizeof(hm),hm};
|
||
|
bool prehash=false;
|
||
|
bool verify;
|
||
|
|
||
|
// 57 bytes
|
||
|
// OCT_fromHex(&D,(char *)"6c82a562cb808d10d632be89c8513ebf6c929f34ddfa8c9f63c9960ef6e348a3528c8a3fcc2f044e39a3fc5b94492f8f032e7549a20098f95b");
|
||
|
OCT_fromHex(&D,(char *)"c4eab05d357007c632f3dbb48489924d552b08fe0c353a0d4a1f00acda2c463afbea67c5e8d2877c5e3bc397a659949ef8021e954e0a12274e");
|
||
|
// OCT_fromHex(&D,(char *)"833fe62409237b9d62ec77587520911e9a759cec1d19755b7da901b96dca3d42ef7822e0d5104127dc05d6dbefde69e3ab2cec7c867c6e2c49");
|
||
|
|
||
|
|
||
|
EDDSA_KEY_PAIR_GENERATE(NULL, &D, &Q);
|
||
|
printf("Secret key= 0x");
|
||
|
OCT_output(&D);
|
||
|
printf("Public key= 0x");
|
||
|
OCT_output(&Q);
|
||
|
printf("\n");
|
||
|
|
||
|
M.len=1; M.val[0]=0x03;
|
||
|
// M.len=3; M.val[0]=0x61; M.val[1]=0x62; M.val[2]=0x63;
|
||
|
CTX.len=3; CTX.val[0]=0x66; CTX.val[1]=0x6F; CTX.val[2]=0x6f;
|
||
|
|
||
|
|
||
|
if (prehash) {
|
||
|
PH_Ed448(&M,&HM);
|
||
|
EDDSA_SIGNATURE(true,&D, NULL,&HM, &SIG);
|
||
|
} else {
|
||
|
EDDSA_SIGNATURE(false,&D, NULL,&M, &SIG);
|
||
|
}
|
||
|
|
||
|
printf("Signature= 0x");
|
||
|
OCT_output(&SIG);
|
||
|
|
||
|
if (prehash) {
|
||
|
PH_Ed448(&M,&HM);
|
||
|
verify=EDDSA_VERIFY(true,&Q, NULL ,&HM, &SIG);
|
||
|
} else {
|
||
|
verify=EDDSA_VERIFY(false,&Q, NULL ,&M, &SIG);
|
||
|
}
|
||
|
if (verify)
|
||
|
printf("Signature is verified\n");
|
||
|
else
|
||
|
printf("Signature is NOT verified\n");
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
int main()
|
||
|
{
|
||
|
int i, res;
|
||
|
unsigned long ran;
|
||
|
|
||
|
char raw[100];
|
||
|
octet RAW = {0, sizeof(raw), raw};
|
||
|
csprng RNG; // Crypto Strong RNG
|
||
|
|
||
|
time((time_t *)&ran);
|
||
|
|
||
|
RAW.len = 100; // fake random seed source
|
||
|
RAW.val[0] = ran;
|
||
|
RAW.val[1] = ran >> 8;
|
||
|
RAW.val[2] = ran >> 16;
|
||
|
RAW.val[3] = ran >> 24;
|
||
|
for (i = 4; i < 100; i++) RAW.val[i] = i;
|
||
|
|
||
|
CREATE_CSPRNG(&RNG, &RAW); // initialise strong RNG
|
||
|
|
||
|
printf("\nTesting EDDSA protocols for curve Ed25519\n");
|
||
|
eddsa_Ed25519(&RNG);
|
||
|
printf("\nTesting EDDSA protocols for curve Ed448\n");
|
||
|
eddsa_Ed448(&RNG);
|
||
|
|
||
|
KILL_CSPRNG(&RNG);
|
||
|
}
|
||
|
|