%PDF- %PDF-
Direktori : /data/down/eBOOKS/Handbook of Applied Cryptography/ |
Current File : //data/down/eBOOKS/Handbook of Applied Cryptography/montmult.c |
/* Author: Pate Williams (c) 1997 Montgomery multiplication. See "Handbook of Applied Cryptography" by Alfred J. Menezes et al Section 14.3.2 pages 600 - 603. */ #include <stdio.h> #include <stdlib.h> #include "lip.h" #define DEBUG void radix_representation(long b, long n, long *a, verylong za) { long i = 0; verylong zb = 0, zq = 0, zr = 0, zx = 0; zintoz(b, &zb); zcopy(za, &zx); do { zdiv(zx, zb, &zq, &zr); a[i++] = ztoint(zr); zcopy(zq, &zx); } while (zscompare(zq, 0l) != 0); while (i < n) a[i++] = 0; zfree(&zb); zfree(&zq); zfree(&zr); zfree(&zx); } void Montgomery_multiplication(long b, long n, verylong zm, verylong zx, verylong zy, verylong *zA) { long i, n1 = n + 1, u, mp, *a, *m, *x, *y; verylong za = 0, zb = 0, zc = 0, zd = 0, zs = 0; a = calloc(n1, sizeof(long)); m = calloc(n1, sizeof(long)); x = calloc(n1, sizeof(long)); y = calloc(n1, sizeof(long)); if (a == 0 || m == 0 || x == 0 || y == 0) { printf("*error*\ncan't get memory from Montgomery"); printf(" multiplication"); exit(1); } zintoz(b, &zb); zinvmod(zm, zb, &za); znegate(&za); mp = zsmod(za, b); radix_representation(b, n1, m, zm); radix_representation(b, n1, x, zx); radix_representation(b, n1, y, zy); zzero(zA); for (i = 0; i < n; i++) { radix_representation(b, n1, a, *zA); u = ((a[0] + x[i] * y[0]) * mp) % b; zsmul(zy, x[i], &za); zsmul(zm, u, &zc); zadd(*zA, za, &zs); zadd(zs, zc, &zd); zsdiv(zd, b, zA); #ifdef DEBUG printf("%ld %ld %ld %ld ", i, x[i], x[i] * y[0], u); zwrite(za); printf(" "); zwrite(zc); printf(" "); zwriteln(*zA); #endif } if (zcompare(*zA, zm) >= 0) { zsub(*zA, zm, &za); zcopy(za, zA); } free(a); free(m); free(x); free(y); zfree(&za); zfree(&zb); zfree(&zc); zfree(&zd); zfree(&zs); } int main(void) { long b = 10, n = 5; verylong zA = 0, zm = 0, zx = 0, zy = 0; zintoz(72639l, &zm); zintoz(5792l, &zx); zintoz(1229l, &zy); Montgomery_multiplication(b, n, zm, zx, zy, &zA); zwriteln(zA); zfree(&zA); zfree(&zm); zfree(&zx); zfree(&zy); return 0; }