blob: e7f0c8daac01ae62681dbe60707e1be1dd3868fa [file] [log] [blame]
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you 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.
*/
/**
* @file test_fp_arithmetics.c
* @author Samuele Andreoli
* @brief Test for aritmetics with FP
*
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "arch.h"
#include "amcl.h"
#include "utils.h"
#include "fp48_YYY.h"
#define LINE_LEN 10000
/*
* Skips n closed brackets.
* Null terminates after the nth bracket and
* returns a pointer to the next char
*/
char* skip_cb(char* str, int n)
{
int i;
char* next=str;
for(i=0; i<n; i++)
{
next = strchr(++next,']');
if (next == NULL)
{
printf("ERROR unexpected test vector\n");
exit(EXIT_FAILURE);
}
}
*(++next) = '\0';
return next++;
}
void read_BIG_XXX(BIG_XXX A, char* string)
{
int len;
char support[LINE_LEN];
BIG_XXX_zero(A);
len = strlen(string)+1;
amcl_hex2bin(string,support,len);
len = (len-1)/2;
BIG_XXX_fromBytesLen(A,support,len);
BIG_XXX_norm(A);
}
void read_FP2_YYY(FP2_YYY *fp2, char* stringx)
{
char *stringy;
BIG_XXX x,y;
stringy = strchr(++stringx,',');
if (stringy == NULL)
{
printf("ERROR unexpected test vector\n");
exit(EXIT_FAILURE);
}
*(stringy)=0;
skip_cb(stringy++,1);
read_BIG_XXX(x,stringx);
read_BIG_XXX(y,stringy);
FP2_YYY_from_BIGs(fp2,x,y);
}
void read_FP4_YYY(FP4_YYY *fp4, char* stringx)
{
char *stringy;
FP2_YYY x,y;
stringy = skip_cb(stringx++,1);
skip_cb(stringy++,1);
read_FP2_YYY(&x,stringx);
read_FP2_YYY(&y,stringy);
FP4_YYY_from_FP2s(fp4,&x,&y);
}
void read_FP8_YYY(FP8_YYY *fp8, char* stringx)
{
char *stringy;
FP4_YYY x,y;
stringy = skip_cb(stringx++,3);
skip_cb(stringy++,3);
read_FP4_YYY(&x,stringx);
read_FP4_YYY(&y,stringy);
FP8_YYY_from_FP4s(fp8,&x,&y);
}
void read_FP16_YYY(FP16_YYY *fp16, char* stringx)
{
char *stringy;
FP8_YYY x,y;
stringy = skip_cb(stringx++,7);
skip_cb(stringy++,7);
read_FP8_YYY(&x,stringx);
read_FP8_YYY(&y,stringy);
FP16_YYY_from_FP8s(fp16,&x,&y);
}
void read_FP48_YYY(FP48_YYY *fp48, char *stringx)
{
char *stringy, *stringz;
FP16_YYY x,y,z;
stringy = skip_cb(stringx++,15);
stringz = skip_cb(stringy++,15);
skip_cb(stringz++,15);
read_FP16_YYY(&x,stringx);
read_FP16_YYY(&y,stringy);
read_FP16_YYY(&z,stringz);
FP48_YYY_from_FP16s(fp48,&x,&y,&z);
}
int main(int argc, char** argv)
{
if (argc != 2)
{
printf("usage: ./test_fp48_arithmetics_ZZZ [path to test vector file]\n");
exit(EXIT_FAILURE);
}
int i = 0, j = 1, k, len = 0;
FILE *fp;
char line[LINE_LEN];
char * linePtr = NULL;
BIG_XXX M, Fr_a, Fr_b;
FP2_YYY Frob;
FP16_YYY FP16aux1;
FP48_YYY FP48aux1, FP48aux2;
char octaux[48*MODBYTES_XXX];
octet OCTaux = {0,sizeof(octaux),octaux};
FP48_YYY FP_48[3], FP_48_frobs[16];
const char* FP48_lines[3] =
{
"FP48_1 = ",
"FP48_2 = ",
"FP48_c = "
};
FP48_YYY FP_48_smul_y_dtype;
const char* FP48smul_y_dtypeline = "FP48smul_y_dtype = ";
FP48_YYY FP_48_smul_y_mtype;
const char* FP48smul_y_mtypeline = "FP48smul_y_mtype = ";
FP48_YYY FP48conj;
const char* FP48conjline = "FP48conj = ";
FP48_YYY FP48usquare;
const char* FP48usquareline = "FP48usquare = ";
FP48_YYY FP48square;
const char* FP48squareline = "FP48square = ";
FP48_YYY FP48mul;
const char* FP48mulline = "FP48mul = ";
FP48_YYY FP48smul_dtype;
const char* FP48smuldtypeline = "FP48smul_dtype = ";
FP48_YYY FP48smul_mtype;
const char* FP48smulmtypeline = "FP48smul_mtype = ";
FP48_YYY FP48inv;
const char* FP48invline = "FP48inv = ";
BIG_XXX BIGsc[18];
const char* BIGsclines[18] =
{
"BIGsc1 = ",
"BIGsc2 = ",
"BIGsc3 = ",
"BIGsc4 = ",
"BIGsc5 = ",
"BIGsc6 = ",
"BIGsc7 = ",
"BIGsc8 = ",
"BIGsc9 = ",
"BIGsc10 = ",
"BIGsc11 = ",
"BIGsc12 = ",
"BIGsc13 = ",
"BIGsc14 = ",
"BIGsc15 = ",
"BIGsc16 = ",
"BIGscs = ",
"BIGsco = "
};
FP48_YYY FP48pow;
const char* FP48powline = "FP48pow = ";
FP48_YYY FP48pinpow;
const char* FP48pinpowline = "FP48pinpow = ";
FP16_YYY FP48compows;
const char* FP48compowsline = "FP48compows = ";
FP16_YYY FP48compow;
const char* FP48compowline = "FP48compow = ";
FP48_YYY FP48pow16;
const char* FP48pow16line = "FP48pow16 = ";
FP48_YYY FP48frob;
const char* FP48frobline = "FP48frob = ";
FP16_YYY FP16trace;
const char* FP16traceline = "FP16trace = ";
BIG_XXX_rcopy(M,Modulus_YYY);
BIG_XXX_rcopy(Fr_a,Fra_YYY);
BIG_XXX_rcopy(Fr_b,Frb_YYY);
FP2_YYY_from_BIGs(&Frob,Fr_a,Fr_b);
// Set to one
FP48_YYY_one(&FP48aux1);
FP48_YYY_copy(&FP48aux2,&FP48aux1);
// Testing equal function
if(!FP48_YYY_equals(&FP48aux1,&FP48aux2))
{
printf("ERROR comparing equal FP48s or copying FP48\n");
exit(EXIT_FAILURE);
}
FP16_YYY_zero(&FP16aux1);
FP48_YYY_from_FP16(&FP48aux1,&FP16aux1);
if(FP48_YYY_equals(&FP48aux1,&FP48aux2))
{
printf("ERROR comparing different FP48s\n");
exit(EXIT_FAILURE);
}
if(!FP48_YYY_iszilch(&FP48aux1) || FP48_YYY_iszilch(&FP48aux2) || FP48_YYY_isunity(&FP48aux1) || !FP48_YYY_isunity(&FP48aux2))
{
printf("ERROR checking iszilch/isunity functions\n");
exit(EXIT_FAILURE);
}
fp = fopen(argv[1], "r");
if (fp == NULL)
{
printf("ERROR opening test vector file\n");
exit(EXIT_FAILURE);
}
while (fgets(line, LINE_LEN, fp) != NULL)
{
i++;
// Read first FP48 and perform some tests on it
if (!strncmp(line,FP48_lines[0], strlen(FP48_lines[0])))
{
len = strlen(FP48_lines[0]);
linePtr = line + len;
read_FP48_YYY(FP_48,linePtr);
// Test setting functions
FP48_YYY_from_FP16(&FP48aux1,&FP_48->a);
if(!FP16_YYY_equals(&FP48aux1.a,&FP_48->a) || !FP16_YYY_iszilch(&FP48aux1.b) || !FP16_YYY_iszilch(&FP48aux1.c))
{
printf("ERROR setting FP48 from a FP16, line %d\n",i);
exit(EXIT_FAILURE);
}
FP48_YYY_from_FP16s(&FP48aux1,&FP_48->a,&FP_48->b,&FP_48->c);
if(!FP48_YYY_equals(&FP48aux1,FP_48))
{
printf("ERROR setting FP48 from three FP16s, line %d\n",i);
exit(EXIT_FAILURE);
}
// Test octet conversion consistency
FP48_YYY_toOctet(&OCTaux,FP_48);
FP48_YYY_fromOctet(&FP48aux1,&OCTaux);
if(!FP48_YYY_equals(&FP48aux1,FP_48))
{
printf("ERROR octet conversion consistency, line %d\n",i);
exit(EXIT_FAILURE);
}
FP48_YYY_copy(FP_48_frobs,FP_48);
for (k=1; k<16; k++)
{
FP48_YYY_copy(FP_48_frobs+k,FP_48_frobs+k-1);
FP48_YYY_frob(FP_48_frobs+k,&Frob,1);
}
}
// Read other FP48s.
for(k = 1; k<3; k++)
{
if (!strncmp(line,FP48_lines[k], strlen(FP48_lines[k])))
{
len = strlen(FP48_lines[k]);
linePtr = line + len;
read_FP48_YYY(FP_48+k,linePtr);
}
}
// Read y for M-TYPE smul test
if (!strncmp(line,FP48smul_y_mtypeline, strlen(FP48smul_y_mtypeline)))
{
len = strlen(FP48smul_y_mtypeline);
linePtr = line + len;
read_FP48_YYY(&FP_48_smul_y_mtype,linePtr);
}
// Read y for D-TYPE smul test
if (!strncmp(line,FP48smul_y_dtypeline, strlen(FP48smul_y_dtypeline)))
{
len = strlen(FP48smul_y_dtypeline);
linePtr = line + len;
read_FP48_YYY(&FP_48_smul_y_dtype,linePtr);
}
// Test FP48_YYY_conj
if (!strncmp(line,FP48conjline, strlen(FP48conjline)))
{
len = strlen(FP48conjline);
linePtr = line + len;
read_FP48_YYY(&FP48conj,linePtr);
FP48_YYY_conj(&FP48aux1,FP_48);
if(!FP48_YYY_equals(&FP48aux1,&FP48conj))
{
printf("ERROR computing conjugate of FP48, line %d\n",i);
exit(EXIT_FAILURE);
}
}
// Test multiplication and commutativity
if (!strncmp(line,FP48mulline, strlen(FP48mulline)))
{
len = strlen(FP48mulline);
linePtr = line + len;
read_FP48_YYY(&FP48mul,linePtr);
FP48_YYY_copy(&FP48aux1,FP_48);
FP48_YYY_mul(&FP48aux1,FP_48+1);
FP48_YYY_copy(&FP48aux2,FP_48+1);
FP48_YYY_mul(&FP48aux2,FP_48);
if(!FP48_YYY_equals(&FP48aux1,&FP48mul) || !FP48_YYY_equals(&FP48aux2,&FP48mul))
{
printf("ERROR computing multiplication of two FP48s, line %d\n",i);
exit(EXIT_FAILURE);
}
}
// Test squaring
if (!strncmp(line,FP48squareline, strlen(FP48squareline)))
{
len = strlen(FP48squareline);
linePtr = line + len;
read_FP48_YYY(&FP48square,linePtr);
FP48_YYY_sqr(&FP48aux1,FP_48);
if(!FP48_YYY_equals(&FP48aux1,&FP48square))
{
printf("ERROR computing square of FP48, line %d\n",i);
exit(EXIT_FAILURE);
}
}
// Test usquaring
if (!strncmp(line,FP48usquareline, strlen(FP48usquareline)))
{
len = strlen(FP48usquareline);
linePtr = line + len;
read_FP48_YYY(&FP48usquare,linePtr);
FP48_YYY_usqr(&FP48aux1,FP_48);
if(!FP48_YYY_equals(&FP48aux1,&FP48usquare))
{
printf("ERROR computing usquare of FP48, line %d\n",i);
exit(EXIT_FAILURE);
}
}
// Test s-multiplication for D-TYPE
if (!strncmp(line,FP48smuldtypeline, strlen(FP48smuldtypeline)))
{
len = strlen(FP48smuldtypeline);
linePtr = line + len;
read_FP48_YYY(&FP48smul_dtype,linePtr);
FP48_YYY_copy(&FP48aux1,FP_48);
FP48_YYY_smul(&FP48aux1,&FP_48_smul_y_dtype,D_TYPE);
if(!FP48_YYY_equals(&FP48aux1,&FP48smul_dtype))
{
printf("ERROR computing s-multiplication for D-TYPE, line %d\n",i);
exit(EXIT_FAILURE);
}
}
// Test s-multiplication for M-TYPE
if (!strncmp(line,FP48smulmtypeline, strlen(FP48smulmtypeline)))
{
len = strlen(FP48smulmtypeline);
linePtr = line + len;
read_FP48_YYY(&FP48smul_mtype,linePtr);
FP48_YYY_copy(&FP48aux1,FP_48);
FP48_YYY_smul(&FP48aux1,&FP_48_smul_y_mtype,M_TYPE);
if(!FP48_YYY_equals(&FP48aux1,&FP48smul_mtype))
{
printf("ERROR computing s-multiplication for M-TYPE, line %d\n",i);
exit(EXIT_FAILURE);
}
}
// Test inverse fuction
if (!strncmp(line,FP48invline, strlen(FP48invline)))
{
len = strlen(FP48invline);
linePtr = line + len;
read_FP48_YYY(&FP48inv,linePtr);
FP48_YYY_inv(&FP48aux1,FP_48);
if(!FP48_YYY_equals(&FP48aux1,&FP48inv))
{
printf("ERROR computing inverse of a FP48, line %d\n",i);
exit(EXIT_FAILURE);
}
}
// Read BIGS
for(k=0; k<18; k++)
{
if (!strncmp(line,BIGsclines[k], strlen(BIGsclines[k])))
{
len = strlen(BIGsclines[k]);
linePtr = line + len;
read_BIG_XXX(BIGsc[k],linePtr);
}
}
// Test power by a BIG
if (!strncmp(line,FP48powline, strlen(FP48powline)))
{
len = strlen(FP48powline);
linePtr = line + len;
read_FP48_YYY(&FP48pow,linePtr);
FP48_YYY_pow(&FP48aux1,FP_48,BIGsc[0]);
if(!FP48_YYY_equals(&FP48aux1,&FP48pow))
{
printf("ERROR computing power of a FP48 by a BIG, line %d\n",i);
exit(EXIT_FAILURE);
}
}
// Test power by a small integer
if (!strncmp(line,FP48pinpowline, strlen(FP48pinpowline)))
{
len = strlen(FP48pinpowline);
linePtr = line + len;
read_FP48_YYY(&FP48pinpow,linePtr);
FP48_YYY_copy(&FP48aux1,FP_48);
FP48_YYY_pinpow(&FP48aux1,j,10);
if(!FP48_YYY_equals(&FP48aux1,&FP48pinpow))
{
printf("ERROR computing power of a FP48 by a small integer, line %d\n",i);
exit(EXIT_FAILURE);
}
j++;
}
// Test fucntion FP48_YYY_compow with small integer [< Modulus mod Curve_Order]
if (!strncmp(line,FP48compowsline, strlen(FP48compowsline)))
{
len = strlen(FP48compowsline);
linePtr = line + len;
read_FP16_YYY(&FP48compows,linePtr);
FP48_YYY_copy(&FP48aux1,FP_48+2);
FP48_YYY_compow(&FP16aux1,&FP48aux1,BIGsc[16],BIGsc[17]);
if(!FP16_YYY_equals(&FP16aux1,&FP48compows))
{
printf("ERROR testing function FP48_compow with small integer, line %d\n",i);
exit(EXIT_FAILURE);
}
}
// Test fucntion FP48_YYY_compow with big integer [> Modulus mod Curve_Order]
if (!strncmp(line,FP48compowline, strlen(FP48compowline)))
{
len = strlen(FP48compowline);
linePtr = line + len;
read_FP16_YYY(&FP48compow,linePtr);
FP48_YYY_copy(&FP48aux1,FP_48+2);
FP48_YYY_compow(&FP16aux1,&FP48aux1,BIGsc[0],BIGsc[17]);
if(!FP16_YYY_equals(&FP16aux1,&FP48compow))
{
printf("ERROR testing function FP48_compow with big integer, line %d\n",i);
exit(EXIT_FAILURE);
}
}
// Test function FP48_YYY_pow16
if (!strncmp(line,FP48pow16line, strlen(FP48pow16line)))
{
len = strlen(FP48pow16line);
linePtr = line + len;
read_FP48_YYY(&FP48pow16,linePtr);
FP48_YYY_pow16(&FP48aux1,FP_48_frobs,BIGsc);
if(!FP48_YYY_equals(&FP48aux1,&FP48pow16))
{
printf("ERROR testing function FP48pow16, line %d\n",i);
exit(EXIT_FAILURE);
}
}
// Raises an FP48 to the power of the internal modulus p, using the Frobenius constant f
if (!strncmp(line,FP48frobline, strlen(FP48frobline)))
{
len = strlen(FP48frobline);
linePtr = line + len;
read_FP48_YYY(&FP48frob,linePtr);
FP48_YYY_copy(&FP48aux1,FP_48);
FP48_YYY_frob(&FP48aux1,&Frob,1);
if(!FP48_YYY_equals(&FP48aux1,&FP48frob) || !FP48_YYY_equals(FP_48_frobs+1,&FP48frob))
{
printf("ERROR in raising FP48 by an internal modulus p, using the Frobenius constant f, line %d\n",i);
exit(EXIT_FAILURE);
}
}
// Test computing trace of FP48
if (!strncmp(line,FP16traceline, strlen(FP16traceline)))
{
len = strlen(FP16traceline);
linePtr = line + len;
read_FP16_YYY(&FP16trace,linePtr);
FP48_YYY_copy(&FP48aux1,&FP_48[0]);
FP48_YYY_trace(&FP16aux1,&FP48aux1);
if(!FP16_YYY_equals(&FP16aux1,&FP16trace))
{
printf("ERROR computing trace of FP48, line %d\n",i);
exit(EXIT_FAILURE);
}
}
}
fclose(fp);
printf("SUCCESS TEST ARITMETIC OF FP48 PASSED\n");
exit(EXIT_SUCCESS);
}