ftu/nonblind.c
2022-09-09 02:47:49 -04:00

131 lines
3.8 KiB
C

// This is a (very rough) test of BLST blind signatures based on run.me from BLST's Python example code
// Do not trust this to be secure, also this doesn't do a lot of the sanity checking yet
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "blst/blst.h"
const byte dst[] = "MY-DST";
double time_taken;
clock_t t;
byte signer_private_key[32];
byte signer_public_key[96];
void printbytes(byte *toprint, int length){
for(int i=0;i<length;i++){
printf("%.2x ", toprint[i]);
}
printf("\n");
}
void signer_key_setup(){
blst_scalar sk;
blst_p2 pk;
blst_p2_affine pk_affine;
byte myikm[32] = {'*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*'};
// On signer's side:
printf("IKM: ");
printbytes(myikm, 32);
blst_keygen(&sk, myikm, 32, 0, 0);
blst_bendian_from_scalar(signer_private_key, &sk);
printf("Secret Key: ");
printbytes(signer_private_key, 32);
blst_sk_to_pk_in_g2(&pk, &sk);
blst_p2_to_affine(&pk_affine, &pk);
blst_p2_affine_compress(signer_public_key, &pk_affine);
printf("Compressed Public Key (affine): ");
printbytes(signer_public_key, 96);
}
void signer(byte *compressed_signature, byte *msg_for_wire){
blst_scalar sk;
blst_p1 msg, signature;
blst_p1_affine msg_affine;
byte debug_print_buf[256];
// get the secret key as a scalar
blst_scalar_from_bendian(&sk, signer_private_key);
// Deserialize the message - it's already a serialized P1 point, we don't need to (literally) rehash it
blst_p1_deserialize(&msg_affine, msg_for_wire);
// i do not know why deserializing always gives you affine points
blst_p1_from_affine(&msg, &msg_affine);
// sign with it
blst_sign_pk_in_g2(&signature, &msg, &sk);
// Serialize and print the signature
blst_p1_serialize(debug_print_buf, &signature);
printf("Signature: ");
printbytes(debug_print_buf, 96);
// Compress and print the signature
blst_p1_compress(compressed_signature, &signature);
printf("Compressed Signature: ");
printbytes(compressed_signature, 48);
}
void verifier(byte *compressed_signature, byte *msg){
blst_p1_affine sig;
blst_p2_affine pk;
blst_p1_uncompress(&sig, compressed_signature);
blst_p2_uncompress(&pk, signer_public_key);
BLST_ERROR returned;
// TODO: check if in g2 group
returned = blst_core_verify_pk_in_g2(&pk, &sig, 1, msg, strlen((char *) msg), dst, strlen((char *) dst), signer_public_key, 96);
if(returned == BLST_SUCCESS){
printf("Verified!\n");
}else{
printf("Not verified!\n");
}
}
// main is the "user" in this test
int main(){
byte compressed_signature[48];
byte msg[] = "assertion";
blst_p1 hash;
byte msg_for_wire_bytes[96];
printf("msg is now %s\n", msg);
// Set up the signer's keys first so that we can know its public key
signer_key_setup();
// Get a hash of the message - we put the signer's public key in aug here, I don't know why
blst_hash_to_g1(&hash, msg, strlen((char *) msg), dst, strlen((char *) dst), signer_public_key, 96);
// Serialize the blinded message to send it over the wire
blst_p1_serialize(msg_for_wire_bytes, &hash);
printf("Hashed for wire: ");
printbytes(msg_for_wire_bytes, 96);
// Send the message off to be signed and get the results back
signer(compressed_signature, msg_for_wire_bytes);
printf("RETURNED SIGNATURE: ");
printbytes(compressed_signature, 48);
//msg[8] = 'A';
printf("msg is now %s\n", msg);
// Now on verifier's side (after compressed_signature, serialized_public_key, and msg are passed over the network)
verifier(compressed_signature, msg);
}