gateway2/Tongsuo-8.4.0/test/recipes/80-test_app_ec_elgamal.t
2026-07-11 13:40:57 +08:00

185 lines
5.6 KiB
Perl

#! /usr/bin/env perl
# Copyright 2022 The Tongsuo Project Authors. All Rights Reserved.
#
# Licensed under the Apache License 2.0 (the "License"). You may not use
# this file except in compliance with the License. You can obtain a copy
# in the file LICENSE in the source distribution or at
# https://github.com/Tongsuo-Project/Tongsuo/blob/master/LICENSE.txt
use strict;
use warnings;
use File::Path 2.00 qw/rmtree/;
use OpenSSL::Test qw/:DEFAULT data_file result_dir/;
use OpenSSL::Test::Utils;
use File::Spec::Functions qw/catfile catdir/;
use Cwd qw/getcwd/;
my $EC_ELGAMAL_TEST_D = getcwd();
my $EC_ELGAMAL_TEST_KEY_D = catdir($EC_ELGAMAL_TEST_D, "ec_elgamal_test_keys");
my $EC_ELGAMAL_TEST_OUT_D = catdir($EC_ELGAMAL_TEST_D, "ec_elgamal_test_outs");
rmtree(${EC_ELGAMAL_TEST_KEY_D}, { safe => 0 });
rmtree(${EC_ELGAMAL_TEST_OUT_D}, { safe => 0 });
mkdir($EC_ELGAMAL_TEST_KEY_D);
mkdir($EC_ELGAMAL_TEST_OUT_D);
sub file_content
{
my($file) = @_;
my $content;
my $opened = open(IN, $file);
if (!$opened) {
$content = "Error.";
} else {
my @lines = <IN>;
foreach my $line (@lines) {
$content .= $line;
}
close(IN);
}
return $content;
}
sub ec_elgamal_encrypt
{
my ($key, $plain) = @_;
if ($plain < 0) {
$plain *= -1;
$plain = "_$plain";
}
my $out_path = catfile($EC_ELGAMAL_TEST_OUT_D, "encrypt-$plain.txt");
ok(run(app(["openssl", "ec_elgamal",
"-encrypt", "-key_in", $key, "-out", $out_path, $plain])), "test ec_elgamal -encrypt");
my $content = file_content($out_path);
if ($content =~ /ciphertext: ([\dA-F]+)/) {
return $1;
}
return 'Error';
}
sub ec_elgamal_decrypt
{
my ($key, $ciphertext) = @_;
my $c16 = substr($ciphertext, 0, 16);
my $out_path = catfile($EC_ELGAMAL_TEST_OUT_D, "decrypt-$c16.txt");
ok(run(app(["openssl", "ec_elgamal",
"-decrypt", "-key_in", $key, "-out", $out_path, $ciphertext])), "test ec_elgamal -decrypt");
my $content = file_content($out_path);
if ($content =~ /plaintext: (-?\d+)/) {
return $1;
}
return 'Error';
}
sub ec_elgamal_add
{
my ($key, $c1, $c2) = @_;
my $c16 = substr($c1, 0, 8);
$c16 .= substr($c2, 0, 8);
my $out_path = catfile($EC_ELGAMAL_TEST_OUT_D, "add-$c16.txt");
ok(run(app(["openssl", "ec_elgamal",
"-add", "-key_in", $key, "-out", $out_path, $c1, $c2])), "test ec_elgamal -add");
my $content = file_content($out_path);
if ($content =~ /result: ([\dA-F]+)/) {
return $1;
}
return 'Error';
}
sub ec_elgamal_sub
{
my ($key, $c1, $c2) = @_;
my $c16 = substr($c1, 0, 8);
$c16 .= substr($c2, 0, 8);
my $out_path = catfile($EC_ELGAMAL_TEST_OUT_D, "sub-$c16.txt");
ok(run(app(["openssl", "ec_elgamal",
"-sub", "-key_in", $key, "-out", $out_path, $c1, $c2])), "test ec_elgamal -sub");
my $content = file_content($out_path);
if ($content =~ /result: ([\dA-F]+)/) {
return $1;
}
return 'Error';
}
sub ec_elgamal_mul
{
my ($key, $c1, $plain) = @_;
if ($plain < 0) {
$plain *= -1;
$plain = "_$plain";
}
my $c16 = substr($c1, 0, 16);
$c16 .= "-$plain";
my $out_path = catfile($EC_ELGAMAL_TEST_OUT_D, "mul-$c16.txt");
ok(run(app(["openssl", "ec_elgamal",
"-mul", "-key_in", $key, "-out", $out_path, $c1, $plain])), "test ec_elgamal -mul");
my $content = file_content($out_path);
if ($content =~ /result: ([\dA-F]+)/) {
return $1;
}
return 'Error';
}
setup("test_app_ec_elgamal");
plan skip_all => "app_ec_elgamal is not supported by this OpenSSL build"
if disabled("ec_elgamal");
plan tests => 139;
my $ec_key_path = catfile($EC_ELGAMAL_TEST_KEY_D, "ec-key.pem");
my $ec_pub_path = catfile($EC_ELGAMAL_TEST_KEY_D, "ec-pub.pem");
my $key_out_path = catfile($EC_ELGAMAL_TEST_OUT_D, "key-out.txt");
my $key_text_out_path = catfile($EC_ELGAMAL_TEST_OUT_D, "key-text-out.txt");
my $pub_out_path = catfile($EC_ELGAMAL_TEST_OUT_D, "pub-out.txt");
my $pub_text_out_path = catfile($EC_ELGAMAL_TEST_OUT_D, "pub-text-out.txt");
# generate ec key
ok(run(app(["openssl", "ecparam",
"-genkey", "-name", "prime256v1", "-out", $ec_key_path])), "generate ec private key");
ok(run(app(["openssl", "ec",
"-in", $ec_key_path, "-pubout", "-out", $ec_pub_path])), "generate ec pub key");
# test ec_elgamal -encrypt/decrypt action
my $e_111 = ec_elgamal_encrypt($ec_pub_path, 111);
my $d_111 = ec_elgamal_decrypt($ec_key_path, $e_111);
ok($e_111 !~ m/Error/, "test ec_elgamal -encrypt");
ok($d_111 !~ m/Error/, "test ec_elgamal -decrypt");
ok($d_111 == 111, "test if ec_elgamal decryption result is equal to 111");
my @test_data = (
[11, 99],
[11, -99],
[-11, 99],
[-11, -99],
[11, 0],
[-11, 0],
[0, 99],
[0, -99],
[99, 11],
[99, -11],
[-99, 11],
[-99, -11],
);
for(my $i = 0; $i < scalar(@test_data); $i++) {
my $x = $test_data[$i][0];
my $y = $test_data[$i][1];
my $e_x = ec_elgamal_encrypt($ec_pub_path, $x);
my $e_y = ec_elgamal_encrypt($ec_pub_path, $y);
my $e_add = ec_elgamal_add($ec_pub_path, $e_x, $e_y);
my $e_sub = ec_elgamal_sub($ec_pub_path, $e_x, $e_y);
my $e_mul = ec_elgamal_mul($ec_pub_path, $e_x, $y);
my $d_add = ec_elgamal_decrypt($ec_key_path, $e_add);
my $d_sub = ec_elgamal_decrypt($ec_key_path, $e_sub);
my $d_mul = ec_elgamal_decrypt($ec_key_path, $e_mul);
ok($d_add == $x + $y, "test ec_elgamal add ($x + ($y))");
ok($d_sub == $x - $y, "test ec_elgamal sub ($x - ($y))");
ok($d_mul == $x * $y, "test ec_elgamal mul ($x * ($y))");
}
rmtree(${EC_ELGAMAL_TEST_KEY_D}, { safe => 0 });
rmtree(${EC_ELGAMAL_TEST_OUT_D}, { safe => 0 });