aboutsummaryrefslogtreecommitdiffstats
path: root/src/pubkey/rw/rw.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/pubkey/rw/rw.cpp')
-rw-r--r--src/pubkey/rw/rw.cpp159
1 files changed, 76 insertions, 83 deletions
diff --git a/src/pubkey/rw/rw.cpp b/src/pubkey/rw/rw.cpp
index 460c740ab..9600ae709 100644
--- a/src/pubkey/rw/rw.cpp
+++ b/src/pubkey/rw/rw.cpp
@@ -8,51 +8,12 @@
#include <botan/rw.h>
#include <botan/numthry.h>
#include <botan/keypair.h>
-#include <botan/look_pk.h>
#include <botan/parsing.h>
#include <algorithm>
namespace Botan {
/*
-* RW_PublicKey Constructor
-*/
-RW_PublicKey::RW_PublicKey(const BigInt& mod, const BigInt& exp)
- {
- n = mod;
- e = exp;
- X509_load_hook();
- }
-
-/*
-* Rabin-Williams Public Operation
-*/
-BigInt RW_PublicKey::public_op(const BigInt& i) const
- {
- if((i > (n >> 1)) || i.is_negative())
- throw Invalid_Argument(algo_name() + "::public_op: i > n / 2 || i < 0");
-
- BigInt r = core.public_op(i);
- if(r % 16 == 12) return r;
- if(r % 8 == 6) return 2*r;
-
- r = n - r;
- if(r % 16 == 12) return r;
- if(r % 8 == 6) return 2*r;
-
- throw Invalid_Argument(algo_name() + "::public_op: Invalid input");
- }
-
-/*
-* Rabin-Williams Verification Function
-*/
-SecureVector<byte> RW_PublicKey::verify(const byte in[], u32bit len) const
- {
- BigInt i(in, len);
- return BigInt::encode(public_op(i));
- }
-
-/*
* Create a Rabin-Williams private key
*/
RW_PrivateKey::RW_PrivateKey(RandomNumberGenerator& rng,
@@ -67,53 +28,18 @@ RW_PrivateKey::RW_PrivateKey(RandomNumberGenerator& rng,
e = exp;
p = random_prime(rng, (bits + 1) / 2, e / 2, 3, 4);
q = random_prime(rng, bits - p.bits(), e / 2, ((p % 8 == 3) ? 7 : 3), 8);
- d = inverse_mod(e, lcm(p - 1, q - 1) >> 1);
- PKCS8_load_hook(rng, true);
+ n = p * q;
if(n.bits() != bits)
throw Self_Test_Failure(algo_name() + " private key generation failed");
- }
-
-/*
-* RW_PrivateKey Constructor
-*/
-RW_PrivateKey::RW_PrivateKey(RandomNumberGenerator& rng,
- const BigInt& prime1, const BigInt& prime2,
- const BigInt& exp, const BigInt& d_exp,
- const BigInt& mod)
- {
- p = prime1;
- q = prime2;
- e = exp;
- d = d_exp;
- n = mod;
-
- if(d == 0)
- d = inverse_mod(e, lcm(p - 1, q - 1) >> 1);
-
- PKCS8_load_hook(rng);
- }
-
-/*
-* Rabin-Williams Signature Operation
-*/
-SecureVector<byte> RW_PrivateKey::sign(const byte in[], u32bit len,
- RandomNumberGenerator&) const
- {
- BigInt i(in, len);
- if(i >= n || i % 16 != 12)
- throw Invalid_Argument(algo_name() + "::sign: Invalid input");
-
- BigInt r;
- if(jacobi(i, n) == 1) r = core.private_op(i);
- else r = core.private_op(i >> 1);
- r = std::min(r, n - r);
- if(i != public_op(r))
- throw Self_Test_Failure(algo_name() + " private operation check failed");
+ d = inverse_mod(e, lcm(p - 1, q - 1) >> 1);
+ d1 = d % (p - 1);
+ d2 = d % (q - 1);
+ c = inverse_mod(q, p);
- return BigInt::encode_1363(r, n.bytes());
+ gen_check(rng);
}
/*
@@ -132,10 +58,12 @@ bool RW_PrivateKey::check_key(RandomNumberGenerator& rng, bool strong) const
try
{
+ PK_Signer this_signer(*this, "EMSA2(SHA-1)");
+ PK_Verifier this_verifier(*this, "EMSA2(SHA-1)");
+
KeyPair::check_key(rng,
- get_pk_signer(*this, "EMSA2(SHA-1)"),
- get_pk_verifier(*this, "EMSA2(SHA-1)")
- );
+ this_signer,
+ this_verifier);
}
catch(Self_Test_Failure)
{
@@ -145,4 +73,69 @@ bool RW_PrivateKey::check_key(RandomNumberGenerator& rng, bool strong) const
return true;
}
+RW_Signature_Operation::RW_Signature_Operation(const RW_PrivateKey& rw) :
+ n(rw.get_n()),
+ e(rw.get_e()),
+ q(rw.get_q()),
+ c(rw.get_c()),
+ powermod_d1_p(rw.get_d1(), rw.get_p()),
+ powermod_d2_q(rw.get_d2(), rw.get_q()),
+ mod_p(rw.get_p())
+ {
+ }
+
+SecureVector<byte>
+RW_Signature_Operation::sign(const byte msg[], u32bit msg_len,
+ RandomNumberGenerator& rng)
+ {
+ if(!blinder.initialized())
+ {
+ BigInt k(rng, n.bits() / 2);
+ blinder = Blinder(power_mod(k, e, n), inverse_mod(k, n), n);
+ }
+
+ BigInt i(msg, msg_len);
+
+ if(i >= n || i % 16 != 12)
+ throw Invalid_Argument("Rabin-Williams: invalid input");
+
+ if(jacobi(i, n) != 1)
+ i >>= 1;
+
+ i = blinder.blind(i);
+
+ BigInt j1 = powermod_d1_p(i);
+ BigInt j2 = powermod_d2_q(i);
+ j1 = mod_p.reduce(sub_mul(j1, j2, c));
+
+ BigInt r = blinder.unblind(mul_add(j1, q, j2));
+
+ r = std::min(r, n - r);
+
+ return BigInt::encode_1363(r, n.bytes());
+ }
+
+SecureVector<byte>
+RW_Verification_Operation::verify_mr(const byte msg[], u32bit msg_len)
+ {
+ BigInt m(msg, msg_len);
+
+ if((m > (n >> 1)) || m.is_negative())
+ throw Invalid_Argument("RW signature verification: m > n / 2 || m < 0");
+
+ BigInt r = powermod_e_n(m);
+ if(r % 16 == 12)
+ return BigInt::encode(r);
+ if(r % 8 == 6)
+ return BigInt::encode(2*r);
+
+ r = n - r;
+ if(r % 16 == 12)
+ return BigInt::encode(r);
+ if(r % 8 == 6)
+ return BigInt::encode(2*r);
+
+ throw Invalid_Argument("RW signature verification: Invalid signature");
+ }
+
}