From 08b90c0a542038f018cae0be6872f7516056ec79 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henrik=20Grubbstr=C3=B6m=20=28Grubba=29?=
 <grubba@grubba.org>
Date: Thu, 4 May 2000 13:22:56 +0200
Subject: [PATCH] Split out the encryption-stuff to simplify the C-version.

Rev: lib/modules/Crypto/_rsa.pike:1.1
Rev: lib/modules/Crypto/rsa.pike:1.19
---
 .gitattributes               |   1 +
 lib/modules/Crypto/_rsa.pike | 121 +++++++++++++++++++++++++++++++++++
 lib/modules/Crypto/rsa.pike  | 101 ++++-------------------------
 3 files changed, 136 insertions(+), 87 deletions(-)
 create mode 100644 lib/modules/Crypto/_rsa.pike

diff --git a/.gitattributes b/.gitattributes
index d16fb4b3c1..19bb79bfc0 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -34,6 +34,7 @@ testfont binary
 /lib/master.pike.in foreign_ident
 /lib/modules/ADT.pmod/Queue.pike foreign_ident
 /lib/modules/ADT.pmod/Table.pmod foreign_ident
+/lib/modules/Crypto/_rsa.pike foreign_ident
 /lib/modules/Crypto/des3.pike foreign_ident
 /lib/modules/Crypto/des3_cbc.pike foreign_ident
 /lib/modules/Crypto/des_cbc.pike foreign_ident
diff --git a/lib/modules/Crypto/_rsa.pike b/lib/modules/Crypto/_rsa.pike
new file mode 100644
index 0000000000..8c124f9bef
--- /dev/null
+++ b/lib/modules/Crypto/_rsa.pike
@@ -0,0 +1,121 @@
+/* $Id: _rsa.pike,v 1.1 2000/05/04 11:22:56 grubba Exp $
+ *
+ * Follow the PKCS#1 standard for padding and encryption.
+ */
+
+#if constant(Gmp.mpz)
+
+#define bignum object(Gmp.mpz)
+#define BIGNUM (Gmp.mpz)
+
+bignum n;  /* modulo */
+bignum e;  /* public exponent */
+bignum d;  /* private exponent (if known) */
+int size;
+
+/* Extra info associated with a private key. Not currently used. */
+   
+bignum p;
+bignum q;
+
+int encrypt_mode; /* For block cipher compatible functions */
+
+object set_public_key(bignum modulo, bignum pub)
+{
+  n = modulo;
+  e = pub;
+  size = n->size(256);
+  if (size < 12)
+    throw( ({ "Crypto.rsa->set_public_key: Too small modulo.\n",
+		backtrace() }) );
+  return this_object();
+}
+
+object set_private_key(bignum priv, array(bignum)|void extra)
+{
+  d = priv;
+  if (extra)
+  {
+    p = extra[0];
+    q = extra[1];
+  }
+  return this_object();
+}
+
+int query_blocksize() { return size - 3; }
+
+bignum rsa_pad(string message, int type, mixed|void random)
+{
+  string cookie;
+  int len;
+
+  len = size - 3 - strlen(message);
+  /*  write(sprintf("%d, %d, %d, %s", len, size, strlen(message), message)); */
+  if (len < 8)
+    throw( ({ "Crypto.rsa->rsa_pad: Too large block.\n",
+		backtrace() }) );
+
+  switch(type)
+  {
+  case 1:
+    cookie = sprintf("%@c", replace(allocate(len), 0, 0xff));
+    break;
+  case 2:
+    if (random)
+      cookie = replace(random(len), "\0", "\1");
+    else
+      cookie = sprintf("%@c", Array.map(allocate(len), lambda(int dummy)
+					{
+					  return predef::random(255) + 1;
+					} ));
+    break;
+  default:
+    throw( ({ "Crypto.rsa->rsa_pad: Unknown type.\n",
+		backtrace() }) );
+  }    
+  return BIGNUM(sprintf("%c", type) + cookie + "\0" + message, 256);
+}
+
+string rsa_unpad(bignum block, int type)
+{
+  string s = block->digits(256);
+  int i = search(s, "\0");
+
+  if ((i < 9) || (strlen(s) != (size - 1)) || (s[0] != type))
+    return 0;
+  return s[i+1..];
+}
+
+object raw_sign(string digest)
+{
+  return rsa_pad(digest, 1, 0)->powm(d, n);
+}
+
+string cooked_sign(string digest)
+{
+  return raw_sign(digest)->digits(256);
+}
+
+int raw_verify(string digest, object s)
+{
+  return s->powm(e, n) == rsa_pad(digest, 1, 0);
+}
+
+string encrypt(string s, mixed|void r)
+{
+  return rsa_pad(s, 2, r)->powm(e, n)->digits(256);
+}
+
+string decrypt(string s)
+{
+  return rsa_unpad(BIGNUM(s, 256)->powm(d, n), 2);
+}
+
+int rsa_size() { return n->size(); }
+
+int public_key_equal (object rsa)
+{
+  return n == rsa->n && e == rsa->e;
+}
+
+#endif
diff --git a/lib/modules/Crypto/rsa.pike b/lib/modules/Crypto/rsa.pike
index df5163ad67..b9d317225e 100644
--- a/lib/modules/Crypto/rsa.pike
+++ b/lib/modules/Crypto/rsa.pike
@@ -1,49 +1,15 @@
-/* $Id: rsa.pike,v 1.18 1999/08/27 15:33:37 grubba Exp $
+/* $Id: rsa.pike,v 1.19 2000/05/04 11:22:56 grubba Exp $
  *
  * Follow the PKCS#1 standard for padding and encryption.
  */
 
 #if constant(Gmp.mpz)
 
+inherit Crypto._rsa;
+
 #define bignum object(Gmp.mpz)
 #define BIGNUM (Gmp.mpz)
 
-import Standards.PKCS;
-
-bignum n;  /* modulo */
-bignum e;  /* public exponent */
-bignum d;  /* private exponent (if known) */
-int size;
-
-/* Extra info associated with a private key. Not currently used. */
-   
-bignum p;
-bignum q;
-
-int encrypt_mode; /* For block cipher compatible functions */
-
-object set_public_key(bignum modulo, bignum pub)
-{
-  n = modulo;
-  e = pub;
-  size = n->size(256);
-  if (size < 12)
-    throw( ({ "Crypto.rsa->set_public_key: Too small modulo.\n",
-		backtrace() }) );
-  return this_object();
-}
-
-object set_private_key(bignum priv, array(bignum)|void extra)
-{
-  d = priv;
-  if (extra)
-  {
-    p = extra[0];
-    q = extra[1];
-  }
-  return this_object();
-}
-
 bignum get_prime(int bits, function r)
 {
   int len = (bits + 7) / 8;
@@ -61,8 +27,6 @@ bignum get_prime(int bits, function r)
   return p;
 }
 
-int query_blocksize() { return size - 3; }
-
 bignum rsa_pad(string message, int type, mixed|void random)
 {
   string cookie;
@@ -95,61 +59,41 @@ bignum rsa_pad(string message, int type, mixed|void random)
   return BIGNUM(sprintf("%c", type) + cookie + "\0" + message, 256);
 }
 
-string rsa_unpad(bignum block, int type)
-{
-  string s = block->digits(256);
-  int i = search(s, "\0");
-
-  if ((i < 9) || (strlen(s) != (size - 1)) || (s[0] != type))
-    return 0;
-  return s[i+1..];
-}
-
+#if constant(_Crypto.rsa)
+// Only the cooked variant is implemented in C. */
 object raw_sign(string digest)
 {
-  return rsa_pad(digest, 1, 0)->powm(d, n);
-}
-
-int raw_verify(string digest, object s)
-{
-  return s->powm(e, n) == rsa_pad(digest, 1, 0);
+  return BIGNUM(cooked_sign(digest), 256);
 }
+#endif /* constant(_Crypto.rsa) */
 
-object sign(string message, program h, mixed|void r)
+object sign(string message, program h)
 {
-  // FIXME: The r argument is ignored and should be removed
-  return raw_sign(Signature.build_digestinfo(message, h()));
+  string digest = Standards.PKCS.Signature.build_digestinfo(message, h());
+  return raw_sign(digest);
 }
 
 int verify(string msg, program h, object sign)
 {
-  // FIXME: Use raw_verify()
-  
   // werror(sprintf("msg: '%s'\n", Crypto.string_to_hex(msg)));
-  string s = Signature.build_digestinfo(msg, h());
+  string s = Standards.PKCS.Signature.build_digestinfo(msg, h());
   // werror(sprintf("rsa: s = '%s'\n", s));
-  // werror(sprintf("decrypted: '%s'\n", sign->powm(e, n)->digits(256)));
-  string s2 = rsa_unpad(sign->powm(e, n), 1);
-  // werror(sprintf("rsa: s2 = '%s'\n", s2));
-  return s == s2;
+  return raw_verify(s, sign);
 }
 
 string sha_sign(string message, mixed|void r)
 {
-  // FIXME: Use raw_sign()
   object hash = Crypto.sha();
   string s;
 
   hash->update(message);
   s = hash->digest();
   s = sprintf("%c%s%c%s", 4, "sha1", strlen(s), s);
-  return rsa_pad(s, 1, r)->powm(d, n)->digits(256);
+  return cooked_sign(s);
 }
   
 int sha_verify(string message, string signature)
 {
-  // FIXME: Use raw_verify()
-  
   object hash = Crypto.sha();
   string s;
   
@@ -157,7 +101,7 @@ int sha_verify(string message, string signature)
   s = hash->digest();
   s = sprintf("%c%s%c%s", 4, "sha1", strlen(s), s);
 
-  return s == rsa_unpad(BIGNUM(signature, 256)->powm(e, n), 1);
+  return raw_verify(s, BIGNUM(signature, 256));
 }
 
 object generate_key(int bits, function|void r)
@@ -198,16 +142,6 @@ object generate_key(int bits, function|void r)
   return this_object();
 }
 
-string encrypt(string s, mixed|void r)
-{
-  return rsa_pad(s, 2, r)->powm(e, n)->digits(256);
-}
-
-string decrypt(string s)
-{
-  return rsa_unpad(BIGNUM(s, 256)->powm(d, n), 2);
-}
-
 object set_encrypt_key(array(bignum) key)
 {
   set_public_key(key[0], key[1]);
@@ -228,11 +162,4 @@ string crypt_block(string s)
   return (encrypt_mode ? encrypt(s) : decrypt(s));
 }
 
-int rsa_size() { return n->size(); }
-
-int public_key_equal (object rsa)
-{
-  return n == rsa->n && e == rsa->e;
-}
-
 #endif
-- 
GitLab