⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 moduli.c

📁 OpenSSH 是 SSH (Secure SHell) 协议的免费开源实现。它用安全、加密的网络连接工具代替了 telnet、ftp、 rlogin、rsh 和 rcp 工具。OpenSSH 支持
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $OpenBSD: moduli.c,v 1.10 2005/01/17 03:25:46 dtucker Exp $ *//* * Copyright 1994 Phil Karn <karn@qualcomm.com> * Copyright 1996-1998, 2003 William Allen Simpson <wsimpson@greendragon.com> * Copyright 2000 Niels Provos <provos@citi.umich.edu> * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *//* * Two-step process to generate safe primes for DHGEX * *  Sieve candidates for "safe" primes, *  suitable for use as Diffie-Hellman moduli; *  that is, where q = (p-1)/2 is also prime. * * First step: generate candidate primes (memory intensive) * Second step: test primes' safety (processor intensive) */#include "includes.h"#include "xmalloc.h"#include "log.h"#include <openssl/bn.h>/* * File output defines *//* need line long enough for largest moduli plus headers */#define QLINESIZE		(100+8192)/* Type: decimal. * Specifies the internal structure of the prime modulus. */#define QTYPE_UNKNOWN		(0)#define QTYPE_UNSTRUCTURED	(1)#define QTYPE_SAFE		(2)#define QTYPE_SCHNORR		(3)#define QTYPE_SOPHIE_GERMAIN	(4)#define QTYPE_STRONG		(5)/* Tests: decimal (bit field). * Specifies the methods used in checking for primality. * Usually, more than one test is used. */#define QTEST_UNTESTED		(0x00)#define QTEST_COMPOSITE		(0x01)#define QTEST_SIEVE		(0x02)#define QTEST_MILLER_RABIN	(0x04)#define QTEST_JACOBI		(0x08)#define QTEST_ELLIPTIC		(0x10)/* * Size: decimal. * Specifies the number of the most significant bit (0 to M). * WARNING: internally, usually 1 to N. */#define QSIZE_MINIMUM		(511)/* * Prime sieving defines *//* Constant: assuming 8 bit bytes and 32 bit words */#define SHIFT_BIT	(3)#define SHIFT_BYTE	(2)#define SHIFT_WORD	(SHIFT_BIT+SHIFT_BYTE)#define SHIFT_MEGABYTE	(20)#define SHIFT_MEGAWORD	(SHIFT_MEGABYTE-SHIFT_BYTE)/* * Using virtual memory can cause thrashing.  This should be the largest * number that is supported without a large amount of disk activity -- * that would increase the run time from hours to days or weeks! */#define LARGE_MINIMUM	(8UL)	/* megabytes *//* * Do not increase this number beyond the unsigned integer bit size. * Due to a multiple of 4, it must be LESS than 128 (yielding 2**30 bits). */#define LARGE_MAXIMUM	(127UL)	/* megabytes *//* * Constant: when used with 32-bit integers, the largest sieve prime * has to be less than 2**32. */#define SMALL_MAXIMUM	(0xffffffffUL)/* Constant: can sieve all primes less than 2**32, as 65537**2 > 2**32-1. */#define TINY_NUMBER	(1UL<<16)/* Ensure enough bit space for testing 2*q. */#define TEST_MAXIMUM    (1UL<<16)#define TEST_MINIMUM    (QSIZE_MINIMUM + 1)/* real TEST_MINIMUM    (1UL << (SHIFT_WORD - TEST_POWER)) */#define TEST_POWER      (3)	/* 2**n, n < SHIFT_WORD *//* bit operations on 32-bit words */#define BIT_CLEAR(a,n)  ((a)[(n)>>SHIFT_WORD] &= ~(1L << ((n) & 31)))#define BIT_SET(a,n)    ((a)[(n)>>SHIFT_WORD] |= (1L << ((n) & 31)))#define BIT_TEST(a,n)   ((a)[(n)>>SHIFT_WORD] & (1L << ((n) & 31)))/* * Prime testing defines *//* Minimum number of primality tests to perform */#define TRIAL_MINIMUM           (4)/* * Sieving data (XXX - move to struct) *//* sieve 2**16 */static u_int32_t *TinySieve, tinybits;/* sieve 2**30 in 2**16 parts */static u_int32_t *SmallSieve, smallbits, smallbase;/* sieve relative to the initial value */static u_int32_t *LargeSieve, largewords, largetries, largenumbers;static u_int32_t largebits, largememory;	/* megabytes */static BIGNUM *largebase;int gen_candidates(FILE *, int, int, BIGNUM *);int prime_test(FILE *, FILE *, u_int32_t, u_int32_t);/* * print moduli out in consistent form, */static intqfileout(FILE * ofile, u_int32_t otype, u_int32_t otests, u_int32_t otries,    u_int32_t osize, u_int32_t ogenerator, BIGNUM * omodulus){	struct tm *gtm;	time_t time_now;	int res;	time(&time_now);	gtm = gmtime(&time_now);	res = fprintf(ofile, "%04d%02d%02d%02d%02d%02d %u %u %u %u %x ",	    gtm->tm_year + 1900, gtm->tm_mon + 1, gtm->tm_mday,	    gtm->tm_hour, gtm->tm_min, gtm->tm_sec,	    otype, otests, otries, osize, ogenerator);	if (res < 0)		return (-1);	if (BN_print_fp(ofile, omodulus) < 1)		return (-1);	res = fprintf(ofile, "\n");	fflush(ofile);	return (res > 0 ? 0 : -1);}/* ** Sieve p's and q's with small factors */static voidsieve_large(u_int32_t s){	u_int32_t r, u;	debug3("sieve_large %u", s);	largetries++;	/* r = largebase mod s */	r = BN_mod_word(largebase, s);	if (r == 0)		u = 0; /* s divides into largebase exactly */	else		u = s - r; /* largebase+u is first entry divisible by s */	if (u < largebits * 2) {		/*		 * The sieve omits p's and q's divisible by 2, so ensure that		 * largebase+u is odd. Then, step through the sieve in		 * increments of 2*s		 */		if (u & 0x1)			u += s; /* Make largebase+u odd, and u even */		/* Mark all multiples of 2*s */		for (u /= 2; u < largebits; u += s)			BIT_SET(LargeSieve, u);	}	/* r = p mod s */	r = (2 * r + 1) % s;	if (r == 0)		u = 0; /* s divides p exactly */	else		u = s - r; /* p+u is first entry divisible by s */	if (u < largebits * 4) {		/*		 * The sieve omits p's divisible by 4, so ensure that		 * largebase+u is not. Then, step through the sieve in		 * increments of 4*s		 */		while (u & 0x3) {			if (SMALL_MAXIMUM - u < s)				return;			u += s;		}		/* Mark all multiples of 4*s */		for (u /= 4; u < largebits; u += s)			BIT_SET(LargeSieve, u);	}}/* * list candidates for Sophie-Germain primes (where q = (p-1)/2) * to standard output. * The list is checked against small known primes (less than 2**30). */intgen_candidates(FILE *out, int memory, int power, BIGNUM *start){	BIGNUM *q;	u_int32_t j, r, s, t;	u_int32_t smallwords = TINY_NUMBER >> 6;	u_int32_t tinywords = TINY_NUMBER >> 6;	time_t time_start, time_stop;	int i, ret = 0;	largememory = memory;	if (memory != 0 &&	   (memory < LARGE_MINIMUM || memory > LARGE_MAXIMUM)) {		error("Invalid memory amount (min %ld, max %ld)",		    LARGE_MINIMUM, LARGE_MAXIMUM);		return (-1);	}	/*	 * Set power to the length in bits of the prime to be generated.	 * This is changed to 1 less than the desired safe prime moduli p.	 */	if (power > TEST_MAXIMUM) {		error("Too many bits: %u > %lu", power, TEST_MAXIMUM);		return (-1);	} else if (power < TEST_MINIMUM) {		error("Too few bits: %u < %u", power, TEST_MINIMUM);		return (-1);	}	power--; /* decrement before squaring */	/*	 * The density of ordinary primes is on the order of 1/bits, so the	 * density of safe primes should be about (1/bits)**2. Set test range	 * to something well above bits**2 to be reasonably sure (but not	 * guaranteed) of catching at least one safe prime.	 */	largewords = ((power * power) >> (SHIFT_WORD - TEST_POWER));	/*	 * Need idea of how much memory is available. We don't have to use all	 * of it.	 */	if (largememory > LARGE_MAXIMUM) {		logit("Limited memory: %u MB; limit %lu MB",		    largememory, LARGE_MAXIMUM);		largememory = LARGE_MAXIMUM;	}	if (largewords <= (largememory << SHIFT_MEGAWORD)) {		logit("Increased memory: %u MB; need %u bytes",		    largememory, (largewords << SHIFT_BYTE));		largewords = (largememory << SHIFT_MEGAWORD);	} else if (largememory > 0) {		logit("Decreased memory: %u MB; want %u bytes",		    largememory, (largewords << SHIFT_BYTE));		largewords = (largememory << SHIFT_MEGAWORD);	}	TinySieve = calloc(tinywords, sizeof(u_int32_t));	if (TinySieve == NULL) {		error("Insufficient memory for tiny sieve: need %u bytes",		    tinywords << SHIFT_BYTE);		exit(1);	}	tinybits = tinywords << SHIFT_WORD;	SmallSieve = calloc(smallwords, sizeof(u_int32_t));	if (SmallSieve == NULL) {		error("Insufficient memory for small sieve: need %u bytes",		    smallwords << SHIFT_BYTE);		xfree(TinySieve);		exit(1);	}	smallbits = smallwords << SHIFT_WORD;	/*	 * dynamically determine available memory	 */	while ((LargeSieve = calloc(largewords, sizeof(u_int32_t))) == NULL)		largewords -= (1L << (SHIFT_MEGAWORD - 2)); /* 1/4 MB chunks */	largebits = largewords << SHIFT_WORD;	largenumbers = largebits * 2;	/* even numbers excluded */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -