📄 11-07.html
字号:
<P>
<B>Applied Cryptography, Second Edition: Protocols, Algorthms, and Source Code in C (cloth)</B>
<FONT SIZE="-1">
<BR>
<I>(Publisher: John Wiley & Sons, Inc.)</I>
<BR>
Author(s): Bruce Schneier
<BR>
ISBN: 0471128457
<BR>
Publication Date: 01/01/96
</FONT>
<P>
<form name="Search" method="GET" action="http://search.earthweb.com/search97/search_redir.cgi">
<INPUT TYPE="hidden" NAME="Action" VALUE="Search">
<INPUT TYPE="hidden" NAME="SearchPage" VALUE="http://search.earthweb.com/search97/samples/forms/srchdemo.htm">
<INPUT TYPE="hidden" NAME="Collection" VALUE="ITK">
<INPUT TYPE="hidden" NAME="ResultTemplate" VALUE="itk-full.hts">
<INPUT TYPE="hidden" NAME="ViewTemplate" VALUE="view.hts">
<font face="arial, helvetica" size=2><b>Search this book:</b></font><br>
<INPUT NAME="queryText" size=50 VALUE=""> <input type="submit" name="submitbutton" value="Go!">
<INPUT type=hidden NAME="section_on" VALUE="on">
<INPUT type=hidden NAME="section" VALUE="http://www.itknowledge.com/reference/standard/0471128457/">
</form>
<!-- Empty Reference Subhead -->
<!--ISBN=0471128457//-->
<!--TITLE=APPLIED CRYPTOGRAPHY, SECOND EDITION: Protocols, Algorithms, and Source Code in C//-->
<!--AUTHOR=Bruce Schneier//-->
<!--PUBLISHER=Wiley Computer Publishing//-->
<!--CHAPTER=11//-->
<!--PAGES=246-249//-->
<!--UNASSIGNED1//-->
<!--UNASSIGNED2//-->
<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="11-06.html">Previous</A></TD>
<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>
<TD><A HREF="11-08.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>
<P><BR></P>
<P>So far, so good. Now, how do you go about finding the inverse of <I>a</I> modulo <I>n?</I> There are a couple of ways. Euclid’s algorithm can also compute the inverse of a number modulo <I>n.</I> Sometimes this is called the <B>extended Euclidean algorithm</B>.</P>
<P>Here’s the algorithm in C<SMALL>++</SMALL>:</P>
<!-- CODE //-->
<PRE>
#define isEven(x) ((x & 0x01) == 0)
#define isOdd(x) (x & 0x01)
#define swap(x,y) (x ^= y, y ^= x, x ^= y)
void ExtBinEuclid(int *u, int *v, int *u1, int *u2, int *u3)
{
// warning: u and v will be swapped if u < v
int k, t1, t2, t3;
if (*u < *v) swap(*u,*v);
for (k = 0; isEven(*u) && isEven(*v); ++k) {
*u >>= 1; *v >>= 1;
}
*u1 = 1; *u2 = 0; *u3 = *u; t1 = *v; t2 = *u-1; t3 = *v;
do {
do {
if (isEven(*u3)) {
if (isOdd(*u1) || isOdd(*u2)) {
*u1 += *v; *u2 += *u;
}
*u1 >>= 1; *u2 >>= 1; *u3 >>= 1;
}
if (isEven(t3) || *u3 < t3) {
swap(*u1,t1); swap(*u2,t2); swap(*u3,t3);
}
} while (isEven(*u3));
while (*u1 < t1 || *u2 < t2) {
*u1 += *v; *u2 += *u;
}
*u1 -= t1; *u2 -= t2; *u3 -= t3;
} while (t3 > 0);
while (*u1 >= *v && *u2 >= *u) {
*u1 -= *v; *u2 -= *u;
}
*u1 <<= k; *u2 <<= k; *u3 <<= k;
}
main(int argc, char **argv) {
int a, b, gcd;
if (argc < 3) {
cerr << "Usage: xeuclid u v" << endl;
return -1;
}
int u = atoi(argv[1]);
int v = atoi(argv[2]);
if (u <= 0 || v <= 0) {
cerr << "Arguments must be positive!" << endl;
return -2;
}
// warning: u and v will be swapped if u < v
ExtBinEuclid(&u, &v, &a, &b, &gcd);
cout << a << " * " << u << " + (-"
<< b << ") * " << v << " = " << gcd << endl;
if (gcd == 1)
cout << "the inverse of " << v << " mod " << u << " is: "
<< u - b << endl;
return 0;
}
</PRE>
<!-- END CODE //-->
<P>I’m not going to prove that it works or give the theory behind it. Details can be found in [863], or in any of the number theory texts previously listed.
</P>
<P>The algorithm is iterative and can be slow for large numbers. Knuth showed that the average number of divisions performed by the algorithm is:</P>
<DL>
<DD>.843*log<SUB>2</SUB>(<I>n</I>) + 1.47
</DL>
<P><FONT SIZE="+1"><B><I>Solving for Coefficients</I></B></FONT></P>
<P>Euclid’s algorithm can be used to solve this class of problems: Given an array of <I>m</I> variables <I>x<SUB><SMALL>1</SMALL></SUB></I>, <I>x<SUB><SMALL>2</SMALL></SUB>,...x<SUB><SMALL>m</SMALL></SUB></I>, find an array of <I>m</I> coefficients, <I>u<SUB><SMALL>1</SMALL></SUB></I>, <I>u<SUB><SMALL>2</SMALL></SUB>...u<SUB><SMALL>m</SMALL></SUB></I>, such that</P>
<DL>
<DD><I>u<SUB><SMALL>1</SMALL></SUB>*x<SUB><SMALL>1</SMALL></SUB> + ...+ u<SUB><SMALL>m</SMALL></SUB>*x<SUB><SMALL>m</SMALL></SUB></I> = 1
</DL>
<P><FONT SIZE="+1"><B><I>Fermat’s Little Theorem</I></B></FONT></P>
<P>If <I>m</I> is a prime, and <I>a</I> is not a multiple of <I>m</I>, then <B>Fermat’s little theorem</B> says</P>
<DL>
<DD><I>am</I> <SUP><SMALL>-1</SMALL></SUP> ≡ 1 (mod <I>m</I>)
</DL>
<P>(Pierre de Fermat, pronounced “Fair-ma, ” was a French mathematician who lived from 1601 to 1665. This theorem has nothing to do with his last theorem.)
</P>
<P><FONT SIZE="+1"><B><I>The Euler Totient Function</I></B></FONT></P>
<P>There is another method for calculating the inverse modulo <I>n</I>, but it’s not always possible to use it. The <B>reduced set of residues</B> mod <I>n</I> is the subset of the complete set of residues that is relatively prime to <I>n.</I> For example, the reduced set of residues mod 12 is {1, 5, 7, 11}. If <I>n</I> is prime, then the reduced set of residues mod <I>n</I> is the set of all numbers from 1 to <I>n</I>- 1. The number 0 is never part of the reduced set of residues for any <I>n</I> not equal to 1.</P>
<P>The <B>Euler totient function</B>, also called the Euler phi function and written as φ(<I>n</I>), is the number of elements in the reduced set of residues modulo <I>n.</I> In other words, φ(<I>n</I>) is the number of positive integers less than <I>n</I> that are relatively prime to <I>n</I> (for any <I>n</I> greater than 1). (Leonhard Euler, pronounced “Oiler, ” was a Swiss mathematician who lived from 1707 to 1783.)</P>
<P>If <I>n</I> is prime, then φ(<I>n</I>) = <I>n</I>- 1. If <I>n</I> = <I>pq</I>, where <I>p</I> and <I>q</I> are prime, then φ(<I>n</I>) = (<I>p</I>- 1)(<I>q</I>- 1). These numbers appear in some public-key algorithms; this is why.</P>
<P>According to <B>Euler’s generalization of Fermat’s little theorem</B>, if gcd(<I>a,n</I>) = 1, then</P>
<DL>
<DD><I>a<SUP><SMALL>φ</I>(<I>n</I>)</SMALL></SUP> mod <I>n</I> = 1
</DL>
<P>Now it is easy to compute <I>a</I><SUP><SMALL>-1</SMALL></SUP> mod <I>n:</I></P>
<DL>
<DD><I>x</I> = a<SUP><SMALL>φ(<I>n</I>)-1</SMALL></SUP> mod <I>n</I>
</DL>
<P>For example, what is the inverse of 5, modulo 7? Since 7 is prime, φ(7) = 7- 1 = 6. So, the inverse of 5, modulo 7, is
</P>
<DL>
<DD>5<SUP><SMALL>6-1</SMALL></SUP> mod 7 = 5<SUP><SMALL>5</SMALL></SUP> mod 7 = 3
</DL>
<P>Both methods for calculating inverses can be extended to solve for <I>x</I> in the general problem (if gcd(<I>a,n</I>) = 1):</P>
<DL>
<DD>(<I>a*x</I>) mod <I>n</I> = b
</DL>
<P>Using Euler’s generalization, solve
</P>
<DL>
<DD><I>x</I> = (<I>b*a</I> <SUP><SMALL>φ(<I>n</I>)-1)</SMALL></SUP> mod <I>n</I>
</DL>
<P>Using Euclid’s algorithm, solve
</P>
<DL>
<DD><I>x</I> = (b*(<I>a</I><SUP><SMALL>-1</SMALL></SUP> mod <I>n</I>)) mod <I>n</I>
</DL>
<P>In general, Euclid’s algorithm is faster than Euler’s generalization for calculating inverses, especially for numbers in the 500-bit range. If gcd(<I>a,n</I>) ≠ 1, all is not lost. In this general case, (<I>a*x</I>) mod <I>n</I> = <I>b</I>, can have multiple solutions or no solution.</P>
<P><FONT SIZE="+1"><B><I>Chinese Remainder Theorem</I></B></FONT></P>
<P>If you know the prime factorization of <I>n</I>, then you can use something called the <B>Chinese remainder theorem</B> to solve a whole system of equations. The basic version of this theorem was discovered by the first-century Chinese mathematician, Sun Tse.</P><P><BR></P>
<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="11-06.html">Previous</A></TD>
<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>
<TD><A HREF="11-08.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>
[an error occurred while processing this directive]
<!-- all of the reference materials (books) have the footer and subfoot reveresed --><!-- reference_subfoot = footer --><!-- reference_footer = subfoot --><!-- BEGIN SUB FOOTER --> <br><br> </TD> </TR> </TABLE> <table width="640" border=0 cellpadding=0 cellspacing=0> <tr> <td align="left" width=135><img src="/images/white.gif" width=100 height="1" alt="" border="0"></td> <!-- END SUB FOOTER -->
<!-- all of the books have the footer and subfoot reveresed --><!-- reference_subfoot = footer --><!-- reference_footer = subfoot --><!-- FOOTER --> <td width="515" align="left" bgcolor="#FFFFFF"><font face="arial, helvetica" size="1"><b><a href="/products.html"><font color="#006666">Products</font></a> | <a href="/contactus.html"><font color="#006666">Contact Us</font></a> | <a href="/aboutus.html"><font color="#006666">About Us</font></a> | <a href="http://www.earthweb.com/corporate/privacy.html" target="_blank"><font color="#006666">Privacy</font></a> | <a href="http://www.itmarketer.com/" target="_blank"><font color="#006666">Ad Info</font></a> | <a href="/"><font color="#006666">Home</font></a></b> <br><br> Use of this site is subject to certain <a href="/agreement.html">Terms & Conditions</a>, <a href="/copyright.html">Copyright © 1996-1999 EarthWeb Inc.</a><br> All rights reserved. Reproduction whole or in part in any form or medium without express written permision of EarthWeb is prohibited.</font><p></td> </tr></table></BODY></HTML><!-- END FOOTER -->
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -