| /* |
| 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. |
| */ |
| |
| /* |
| Run through the flow of encrypting, ecapsulating and signing a message |
| */ |
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <amcl/utils.h> |
| #include <amcl/randapi.h> |
| #include <amcl/bls_BLS381.h> |
| #include <oqs/oqs.h> |
| #include <amcl/pqnist.h> |
| |
| #define G2LEN 4*BFS_BLS381 |
| #define SIGLEN BFS_BLS381+1 |
| |
| int main() |
| { |
| int i,rc; |
| |
| // Seed value for CSPRNG |
| char seed[PQNIST_SEED_LENGTH]; |
| octet SEED = {sizeof(seed),sizeof(seed),seed}; |
| |
| csprng RNG; |
| |
| // AES Key |
| char k[PQNIST_AES_KEY_LENGTH]; |
| octet K= {0,sizeof(k),k}; |
| |
| // Initialization vectors |
| char iv[PQNIST_AES_IV_LENGTH]; |
| octet IV= {0,sizeof(iv),iv}; |
| char iv2[PQNIST_AES_IV_LENGTH]; |
| octet IV2= {0,sizeof(iv2),iv2}; |
| |
| // Message to be sent to Bob |
| char p[256]; |
| octet P = {0, sizeof(p), p}; |
| OCT_jstring(&P,"Hello Bob! This is a message from Alice"); |
| |
| // Pad message |
| int l = 16 - (P.len % 16); |
| if (l < 16) |
| { |
| OCT_jbyte(&P,0,l); |
| } |
| |
| // AES CBC ciphertext |
| char c[256]; |
| octet C = {0, sizeof(c), c}; |
| |
| // non random seed value |
| for (i=0; i<PQNIST_SEED_LENGTH; i++) SEED.val[i]=i+1; |
| printf("SEED: "); |
| OCT_output(&SEED); |
| printf("\n"); |
| |
| // initialise random number generator |
| CREATE_CSPRNG(&RNG,&SEED); |
| |
| // Generate 256 bit AES Key |
| K.len=PQNIST_AES_KEY_LENGTH; |
| generateRandom(&RNG,&K); |
| |
| // Generate SIKE and BLS keys |
| |
| // Bob's SIKE keys |
| uint8_t SIKEpk[OQS_KEM_sike_p751_length_public_key]; |
| uint8_t SIKEsk[OQS_KEM_sike_p751_length_secret_key]; |
| |
| // Alice's BLS keys |
| char BLSsk[BGS_BLS381]; |
| char BLSpk[G2LEN]; |
| |
| rc = pqnist_sike_keys(seed, SIKEpk, SIKEsk); |
| if (rc) |
| { |
| fprintf(stderr, "FAILURE pqnist_sike_keys rc: %d\n", rc); |
| printf("FAILURE\n"); |
| exit(EXIT_FAILURE); |
| } |
| |
| rc = pqnist_bls_keys(seed, BLSpk, BLSsk); |
| if (rc) |
| { |
| fprintf(stderr, "FAILURE pqnist_bls_keys rc: %d\n", rc); |
| printf("FAILURE\n"); |
| exit(EXIT_FAILURE); |
| } |
| |
| // BLS signature |
| char S[SIGLEN]; |
| |
| // SIKE encapsulated key |
| uint8_t ek[OQS_KEM_sike_p751_length_ciphertext]; |
| |
| // Alice |
| |
| printf("Alice Key: "); |
| amcl_print_hex(K.val, K.len); |
| |
| // Random initialization value |
| IV.len=PQNIST_AES_IV_LENGTH; |
| generateRandom(&RNG,&IV); |
| printf("Alice IV: "); |
| OCT_output(&IV); |
| |
| printf("Alice Plaintext: "); |
| OCT_output(&P); |
| |
| printf("Alice Plaintext: "); |
| OCT_output_string(&P); |
| printf("\n"); |
| |
| // Copy plaintext |
| OCT_copy(&C,&P); |
| |
| // Encrypt plaintext |
| pqnist_aes_cbc_encrypt(K.val, K.len, IV.val, C.val, C.len); |
| |
| printf("Alice Ciphertext: "); |
| OCT_output(&C); |
| |
| generateRandom(&RNG,&IV2); |
| printf("Alice IV2: "); |
| OCT_output(&IV2); |
| |
| // Generate an AES which is ecapsulated using SIKE. Use this key to |
| // AES encrypt the K parameter. |
| rc = pqnist_encapsulate_encrypt(K.val, K.len, IV2.val, SIKEpk, ek); |
| if(rc) |
| { |
| fprintf(stderr, "FAILURE pqnist_encapsulate_encrypt rc: %d\n", rc); |
| exit(EXIT_FAILURE); |
| } |
| |
| printf("Alice encrypted key: "); |
| OCT_output(&K); |
| |
| // Bob |
| |
| // Obtain encapsulated AES key and decrypt K |
| rc = pqnist_decapsulate_decrypt(K.val, K.len, IV2.val, SIKEsk, ek); |
| if(rc) |
| { |
| fprintf(stderr, "FAILURE pqnist_decapsulate_decrypt rc: %d\n", rc); |
| exit(EXIT_FAILURE); |
| } |
| |
| printf("Bob Key: "); |
| amcl_print_hex(K.val, K.len); |
| |
| printf("Bob IV "); |
| OCT_output(&IV); |
| |
| printf("Bob Ciphertext: "); |
| OCT_output(&P); |
| |
| pqnist_aes_cbc_decrypt(K.val, K.len, IV.val, C.val, C.len); |
| |
| printf("Bob Plaintext: "); |
| OCT_output(&C); |
| |
| printf("Bob Plaintext: "); |
| OCT_output_string(&C); |
| printf("\n"); |
| |
| // Compare sent and recieved message (returns 0 for failure) |
| rc = OCT_comp(&P,&C); |
| if(!rc) |
| { |
| fprintf(stderr, "FAILURE OCT_comp rc: %d\n", rc); |
| printf("FAILURE\n"); |
| exit(EXIT_FAILURE); |
| } |
| |
| // Sign message |
| |
| // Alice signs message |
| rc = pqnist_bls_sign(P.val, BLSsk, S); |
| if(rc) |
| { |
| fprintf(stderr, "FAILURE pqnist_bls_sign rc: %d\n", rc); |
| exit(EXIT_FAILURE); |
| } |
| |
| // Bob verifies message |
| rc = pqnist_bls_verify(P.val, BLSpk, S); |
| if (rc) |
| { |
| fprintf(stderr, "FAILURE: verify failed!\n errorCode %d", rc); |
| printf("FAILURE\n"); |
| exit(EXIT_FAILURE); |
| } |
| |
| // clear memory |
| OQS_MEM_cleanse(SIKEsk, OQS_KEM_sike_p751_length_secret_key); |
| OCT_clear(&K); |
| OCT_clear(&IV); |
| OCT_clear(&P); |
| KILL_CSPRNG(&RNG); |
| |
| printf("SUCCESS\n"); |
| exit(EXIT_SUCCESS); |
| } |