use strict;
use warnings;
use Test::More;

use Crypt::PK::RSA;
use Crypt::PK::ECC;

my $rsa = Crypt::PK::RSA->new;
my $ec  = Crypt::PK::ECC->new;
ok($rsa, "RSA new");
ok($ec,  "ECC new");

### RSA

for my $f (qw/jwk_rsa-priv.json jwk_rsa-priv1.json jwk_rsa-pub1.json /) {
  $rsa->import_key("t/data/$f");
  my $kh = $rsa->key2hash;
  ok($kh->{N}, "RSA N test $f");
  ok($kh->{e}, "RSA e test $f");
}

my $RSA1 = {
  d => "5F8713B5E258FE09F81583EC5C1F2B7578B1E6FC2C83514B37913711A1BA449A151FE1CB2CA0FD33B771E68A3B1944649DC867AD1C1E5240BB853E5F24B33459B14028D2D6636BEFEC1E8DA974B352FC53D3F6127EA8A3C29DD14F3941682C56A78768164E4DDA8F06CBF9C734AAE8003224278EA9454A21B17CB06D178075868CC05B3DB6FF1DFDC3D56378B4EDADEDF0C37A4CDC26D1D49AC26F6FE3B5220A5DD29396621BBC688CF2EEE2C6E0D54DA3C782014CD0739DB252CC51CAEBA8D3F1B824BAAB24D068EC903264D7D678AB08F06EC9E7E23D960628B744BF94B3694656463C7E417399ED73D076C891FCF463A9AA9CE62DA9CD17E237DC2A8002F1",
  dP => "1B8B0F5E473A61AF72F28256F7F20B8F8C6EA69BB49738BF1FB553912F318F949D5F7728134A22998C31222D9E99302E7B450E6B97698051B2049E1CF2D436545E34D9746E80A0D33FC6A4621168E6D000EFB41EFCD9ADB9865CDC2DE6DC8DB81B61AF479B120F153200DDB3ABC2DF9FD1149ACEAB63739BF187A22A44E2063D",
  dQ => "1B8B0F5E473A61AF72F28256F7F20B8F8C6EA69BB49738BF1FB553912F318F949D5F7728134A22998C31222D9E99302E7B450E6B97698051B2049E1CF2D436545E34D9746E80A0D33FC6A4621168E6D000EFB41EFCD9ADB9865CDC2DE6DC8DB81B61AF479B120F153200DDB3ABC2DF9FD1149ACEAB63739BF187A22A44E2063D",
  e => "10001",
  N => "D2FC7B6A0A1E6C67104AEB8F88B257669B4DF679DDAD099B5C4A6CD9A88015B5A133BF0B856C7871B6DF000B554FCEB3C2ED512BB68F145C6E8434752FAB52A1CFC124408F79B58A4578C16428855789F7A249E384CB2D9FAE2D67FD96FB926C198E077399FDC815C0AF097DDE5AADEFF44DE70E827F4878432439BFEEB96068D0474FC50D6D90BF3A98DFAF1040C89C02D692AB3B3C2896609D86FD73B774CE0740647CEEEAA310BD12F985A8EB9F59FDD426CEA5B2120F4F2A34BCAB764B7E6C54D6840238BCC40587A59E66ED1F33894577635C470AF75CF92C20D1DA43E1BFC419E222A6F0D0BB358C5E38F9CB050AEAFE904814F1AC1AA49CCA9EA0CA83",
  p => "F378BEEC8BCC197A0C5C2B24BFBDD32ABF3ADFB1623BB676EF3BFCA23EA96D6510C8B3D0050C6D3D59F00F6D11FBAD1E4C3983DAE8E732DE4FA2A32B9BC45F98D855583B638CC9823233A949789C1478FB5CEB95218432A955A558487A74DDFA19565893DDCDF0173DBD8E35C72F01F51CF3386550CD7BCD12F9FB3B49D56DFB",
  q => "DDD7CE47D72E62AFB44BE9A414BCE022D80C11F173076AB78567A132E1B4A02BAA9DBDEFA1B2F2BA6AA355940ED5D22B7708139C276963305C39F5B9AF7EF40055E38967EDFCD1848A8BE89E2CE12A9A3D5554BBF13CC583190876B79C45ECEC67ED6461DFECD6A0DBC6D9031207C0213006F4B527003BA7E2F21C6FAC9E9719",
  qP => "1B233FA7A26B5F24A2CF5B6816029B595F89748DE3438CA9BBDADB316C77AD02417E6B7416863381421911514470EAB07A644DF35CE80C069AF819342963460E3247643743985856DC037B948FA9BB193F987646275D6BC7247C3B9E572D27B748F9917CAC1923AC94DB8671BD0285608B5D95D50A1B33BA21AEB34CA8405515",
  size => 256,
  type => 1,
};

my $RSA2 = {
  d => "",
  dP => "",
  dQ => "",
  e => "10001",
  N => "D2FC7B6A0A1E6C67104AEB8F88B257669B4DF679DDAD099B5C4A6CD9A88015B5A133BF0B856C7871B6DF000B554FCEB3C2ED512BB68F145C6E8434752FAB52A1CFC124408F79B58A4578C16428855789F7A249E384CB2D9FAE2D67FD96FB926C198E077399FDC815C0AF097DDE5AADEFF44DE70E827F4878432439BFEEB96068D0474FC50D6D90BF3A98DFAF1040C89C02D692AB3B3C2896609D86FD73B774CE0740647CEEEAA310BD12F985A8EB9F59FDD426CEA5B2120F4F2A34BCAB764B7E6C54D6840238BCC40587A59E66ED1F33894577635C470AF75CF92C20D1DA43E1BFC419E222A6F0D0BB358C5E38F9CB050AEAFE904814F1AC1AA49CCA9EA0CA83",
  p => "",
  q => "",
  qP => "",
  size => 256,
  type => 0,
};

{
  $rsa->import_key($RSA1);
  my $kh = $rsa->key2hash;
  is($kh->{N},  $RSA1->{N},  "RSA N test HASH1");
  is($kh->{e},  $RSA1->{e},  "RSA e test HASH1");
  is($kh->{p},  $RSA1->{p},  "RSA private p test HASH1");
  is($kh->{q},  $RSA1->{q},  "RSA private q test HASH1");
  is($kh->{d},  $RSA1->{d},  "RSA private d test HASH1");
  is($kh->{dP}, $RSA1->{dP}, "RSA private dP test HASH1");
  is($kh->{dQ}, $RSA1->{dQ}, "RSA private dQ test HASH1");
  is($kh->{qP}, $RSA1->{qP}, "RSA private qP test HASH1");
  ok($rsa->is_private, "RSA private test HASH1");
  my $jwk = $rsa->export_key_jwk('private');
  my $jwkp = $rsa->export_key_jwk('public');
  ### jwk re-import private key
  $rsa->import_key(\$jwk);
  $kh = $rsa->key2hash;
  ok($rsa->is_private, "RSA private test JWK1");
  is($kh->{N},  $RSA1->{N},  "RSA N test JWK1");
  is($kh->{e},  $RSA1->{e},  "RSA e test JWK1");
  is($kh->{p},  $RSA1->{p},  "RSA private p test JWK1");
  is($kh->{q},  $RSA1->{q},  "RSA private q test JWK1");
  is($kh->{d},  $RSA1->{d},  "RSA private d test JWK1");
  is($kh->{dP}, $RSA1->{dP}, "RSA private dP test JWK1");
  is($kh->{dQ}, $RSA1->{dQ}, "RSA private dQ test JWK1");
  is($kh->{qP}, $RSA1->{qP}, "RSA private qP test JWK1");
  ### jwk re-import public key
  $rsa->import_key(\$jwkp);
  $kh = $rsa->key2hash;
  ok(!$rsa->is_private, "RSA !private test JWK2");
  is($kh->{N},  $RSA1->{N}, "RSA N test JWK2");
  is($kh->{e},  $RSA1->{e}, "RSA e test JWK2");
  is($kh->{p},  "", "RSA private p test JWK2");
  is($kh->{q},  "", "RSA private q test JWK2");
  is($kh->{d},  "", "RSA private d test JWK2");
  is($kh->{dP}, "", "RSA private dP test JWK2");
  is($kh->{dQ}, "", "RSA private dQ test JWK2");
  is($kh->{qP}, "", "RSA private qP test JWK2");
}

{
  $rsa->import_key($RSA2);
  my $kh = $rsa->key2hash;
  is($kh->{N},  $RSA1->{N}, "RSA N test HASH2");
  is($kh->{e},  $RSA1->{e}, "RSA e test HASH2");
  is($kh->{p},  "", "RSA private p test HASH2");
  is($kh->{q},  "", "RSA private q test HASH2");
  is($kh->{d},  "", "RSA private d test HASH2");
  is($kh->{dP}, "", "RSA private dP test HASH2");
  is($kh->{dQ}, "", "RSA private dQ test HASH2");
  is($kh->{qP}, "", "RSA private qP test HASH2");
  ok(!$rsa->is_private, "RSA private test HASH2");
}

### ECC

for my $f (qw/jwk_ec-priv1.json jwk_ec-pub.json jwk_ec-pub1.json/) {
  $ec->import_key("t/data/$f");
  my $kh = $ec->key2hash;
  ok($kh->{pub_x}, "EC x test $f");
  ok($kh->{pub_y}, "EC y test $f");
}

my $EC1 = {
  curve_A        => "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC",
  curve_B        => "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B",
  curve_bits     => 256,
  curve_bytes    => 32,
  curve_cofactor => 1,
  curve_Gx       => "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296",
  curve_Gy       => "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5",
  curve_name     => "secp256r1",
  curve_order    => "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551",
  curve_prime    => "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
  k              => "F3BD0C07A81FB932781ED52752F60CC89A6BE5E51934FE01938DDB55D8F77801",
  pub_x          => "30A0424CD21C2944838A2D75C92B37E76EA20D9F00893A3B4EEE8A3C0AAFEC3E",
  pub_y          => "E04B65E92456D9888B52B379BDFBD51EE869EF1F0FC65B6659695B6CCE081723",
  size           => 32,
  type           => 1,
};

my $EC2 = {
  curve_A        => "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC",
  curve_B        => "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B",
  curve_bits     => 256,
  curve_bytes    => 32,
  curve_cofactor => 1,
  curve_Gx       => "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296",
  curve_Gy       => "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5",
  curve_name     => "secp256r1",
  curve_order    => "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551",
  curve_prime    => "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
  k              => "",
  pub_x          => "30A0424CD21C2944838A2D75C92B37E76EA20D9F00893A3B4EEE8A3C0AAFEC3E",
  pub_y          => "E04B65E92456D9888B52B379BDFBD51EE869EF1F0FC65B6659695B6CCE081723",
  size           => 32,
  type           => 0,
};

{
  $ec->import_key($EC1);
  my $kh = $ec->key2hash;
  is($kh->{pub_x}, $EC1->{pub_x}, "EC x test HASH1");
  is($kh->{pub_y}, $EC1->{pub_y}, "EC y test HASH1");
  is($kh->{k},     $EC1->{k},     "EC k test HASH1");
  is($kh->{curve_name}, "secp256r1", "EC curve test HASH1");
  ok($ec->is_private, "EC private test HASH1");
  my $jwk = $ec->export_key_jwk('private');
  my $jwkp = $ec->export_key_jwk('public');
  ### jwk re-import private key
  $ec->import_key(\$jwk);
  $kh = $ec->key2hash;
  is($kh->{pub_x}, $EC1->{pub_x}, "EC x test JWK1");
  is($kh->{pub_y}, $EC1->{pub_y}, "EC y test JWK1");
  is($kh->{k},     $EC1->{k},     "EC k test JWK1");
  is($kh->{curve_name}, "secp256r1", "EC curve test JWK1");
  ok($ec->is_private, "EC private test JWK1");
  ### jwk re-import public key
  $ec->import_key(\$jwkp);
  $kh = $ec->key2hash;
  is($kh->{pub_x}, $EC1->{pub_x}, "EC x test JWK2");
  is($kh->{pub_y}, $EC1->{pub_y}, "EC y test JWK2");
  is($kh->{k}, "", "EC k test JWK2");
  is($kh->{curve_name}, "secp256r1", "EC curve test JWK2");
  ok(!$ec->is_private, "EC !private test JWK2");
}

{
  $ec->import_key($EC2);
  my $kh = $ec->key2hash;
  is($kh->{pub_x}, $EC1->{pub_x}, "EC x test HASH2");
  is($kh->{pub_y}, $EC1->{pub_y}, "EC y test HASH2");
  is($kh->{k}, "", "EC k test HASH2");
  is($kh->{curve_name}, "secp256r1", "EC curve test HASH2");
  ok(!$ec->is_private, "EC private test HASH2");
}

done_testing;