blob: 22e1567eb52dac25841a535d43cc17bc8e84888e [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.
*/
#include "arch.h"
#include "amcl.h"
#include "utils.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "bls_ietf_ZZZ.h"
#define LINE_LEN 1000
//#define DEBUG
int main(int argc, char** argv)
{
if (argc != 2) {
printf("ERROR Not enough input arguments\n");
exit(EXIT_FAILURE);
}
BIG_XXX x_re;
BIG_XXX x_im;
BIG_XXX y_re;
BIG_XXX y_im;
FP2_YYY x2;
FP2_YYY y2;
ECP2_ZZZ P2;
ECP2_ZZZ P2_prime;
// Variables for file parsing
FILE *fp = NULL;
char line[LINE_LEN];
const char *linePtr = NULL;
unsigned int l1 = 0;
bool readLine = false;
int lineNo = 0;
const char *dst_str = "dst = ";
const char *msg_str = "msg = ";
const char *Px_re_str = "P.x_re = ";
const char *Px_im_str = "P.x_im = ";
const char *Py_re_str = "P.y_re = ";
const char *Py_im_str = "P.y_im = ";
char dst[50];
char *msg = NULL;
char *Px_re = NULL;
char *Px_im = NULL;
char *Py_re = NULL;
char *Py_im = NULL;
int dst_len = 0;
int msg_len = 0;
int Px_re_len = 0;
int Px_im_len = 0;
int Py_re_len = 0;
int Py_im_len = 0;
int ret = 0;
// Open file
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) {
readLine = true;
// Read the Domain Separator Tag (DST) value
if (!strncmp(line, dst_str, strlen(dst_str))) {
#ifdef DEBUG
printf("line %d %s\n", lineNo,line);
#endif
// Find hex value in string
linePtr = line + strlen(dst_str);
// Allocate memory
l1 = (unsigned int)strlen(linePtr) - 1;
dst_len = l1;
for(int i = 0; i < dst_len; i++)
dst[i] = linePtr[i];
}
// Read the message
if (!strncmp(line, msg_str, strlen(msg_str))) {
#ifdef DEBUG
printf("line %d %s\n", lineNo,line);
#endif
// Find hex value in string
linePtr = line + strlen(msg_str);
// Allocate memory
l1 = (unsigned int)strlen(linePtr) - 1;
msg_len = l1;
msg = (char*) malloc(msg_len);
if (msg == NULL)
exit(EXIT_FAILURE);
for(int i = 0; i < msg_len; i++)
msg[i] = linePtr[i];
}
// Read the expected output point (real part of P_x)
if (!strncmp(line, Px_re_str, strlen(Px_re_str))) {
#ifdef DEBUG
printf("line %d %s\n", lineNo,line);
#endif
// Find hex value in string
linePtr = line + strlen(Px_re_str);
// Allocate memory
l1 = (unsigned int)strlen(linePtr) - 1;
Px_re_len = l1 / 2;
Px_re = (char*) malloc(Px_re_len);
if (Px_re == NULL)
exit(EXIT_FAILURE);
amcl_hex2bin(linePtr, Px_re, l1);
BIG_XXX_fromBytes(x_re, Px_re);
}
// Read the expected output point (imaginary part of P_x)
if (!strncmp(line, Px_im_str, strlen(Px_im_str))) {
#ifdef DEBUG
printf("line %d %s\n", lineNo,line);
#endif
// Find hex value in string
linePtr = line + strlen(Px_im_str);
// Allocate memory
l1 = (unsigned int)strlen(linePtr) - 1;
Px_im_len = l1 / 2;
Px_im = (char*) malloc(Px_im_len);
if (Px_im == NULL)
exit(EXIT_FAILURE);
amcl_hex2bin(linePtr, Px_im, l1);
BIG_XXX_fromBytes(x_im, Px_im);
}
// Read the expected output point (real part of P_y)
if (!strncmp(line, Py_re_str, strlen(Py_re_str))) {
#ifdef DEBUG
printf("line %d %s\n", lineNo,line);
#endif
// Find hex value in string
linePtr = line + strlen(Py_re_str);
// Allocate memory
l1 = (unsigned int)strlen(linePtr) - 1;
Py_re_len = l1 / 2;
Py_re = (char*) malloc(Py_re_len);
if (Py_re == NULL)
exit(EXIT_FAILURE);
amcl_hex2bin(linePtr, Py_re, l1);
BIG_XXX_fromBytes(y_re, Py_re);
}
// Read the expected output point (imaginary part of P_y)
if (!strncmp(line, Py_im_str, strlen(Py_im_str))) {
#ifdef DEBUG
printf("line %d %s\n", lineNo,line);
#endif
// Find hex value in string
linePtr = line + strlen(Py_im_str);
// Allocate memory
l1 = (unsigned int)strlen(linePtr) - 1;
Py_im_len = l1 / 2;
Py_im = (char*) malloc(Py_im_len);
if (Py_im == NULL)
exit(EXIT_FAILURE);
amcl_hex2bin(linePtr, Py_im, l1);
octet msg_oct = {msg_len, msg_len, msg};
octet dst_oct = {dst_len, dst_len, dst};
BIG_XXX_fromBytes(y_im, Py_im);
FP2_YYY_from_BIGs(&x2, x_re, x_im);
FP2_YYY_from_BIGs(&y2, y_re, y_im);
ECP2_ZZZ_set(&P2, &x2, &y2);
if (strncmp(dst, "QUUX-V01-CS02-with-BLS12381G2_XMD:SHA-256_SSWU_RO_", sizeof(dst)) == 0) {
ret = BLS_IETF_ZZZ_hash2curve_G2(&P2_prime, &msg_oct, &dst_oct);
if (ECP2_ZZZ_equals(&P2, &P2_prime) == 0 || ret) {
printf("TEST BLS_IETF_ZZZ_hash2curve_G2 FAILED LINE %d\n",lineNo);
exit(EXIT_FAILURE);
}
}
else if (strncmp(dst, "QUUX-V01-CS02-with-BLS12381G2_XMD:SHA-256_SSWU_NU_", sizeof(dst)) == 0) {
ret = BLS_IETF_ZZZ_encode2curve_G2(&P2_prime, &msg_oct, &dst_oct);
if (ECP2_ZZZ_equals(&P2, &P2_prime) == 0 || ret) {
printf("TEST BLS_IETF_ZZZ_encode2curve_G2 FAILED LINE %d\n",lineNo);
exit(EXIT_FAILURE);
}
}
else {
printf("WRONG DST - FAILED AT LINE %d\n",lineNo);
exit(EXIT_FAILURE);
}
free(msg);
free(Px_re);
free(Px_im);
free(Py_re);
free(Py_im);
msg = NULL;
Px_re = NULL;
Px_im = NULL;
Py_re = NULL;
Py_im = NULL;
}
lineNo++;
}
fclose(fp);
if (!readLine) {
printf("ERROR No test vectors\n");
exit(EXIT_FAILURE);
}
printf("SUCCESS TEST BLS12-381_HASH2CURVE_G2 PASSED\n");
exit(EXIT_SUCCESS);
}